我看讨论区很多人都70pts,但是不知道为什么。。。
错误信息:Wrong Answer.wrong answer Unconnected graph.
但是我判断是否连通了呀,有没有大佬帮忙看看为什么
思路:二分+kruskal,开两个结构体存边,分别存一级公路和二级+一级公路,先取k个最小的一级公路并且标记一下,然后再取二级
难道贪心错了吗
#include<bits/stdc++.h>
#define PII pair<int,int>
#define fir first
#define sec second
#define nowp edges1[i].num
using namespace std;
const int N=3e5+10,M=2e5+10;
const int inf=0x3f3f3f3f;
int n,m,m1,k,p[M],tt;
PII ans[M];
struct edge{
int x,y,w,num,kd;
}edges1[M],edges2[M];
bool st[M];
bool cmp(edge xx,edge yy){
return xx.w<yy.w;
}
bool cmp1(PII xx,PII yy){return xx.fir<yy.fir;}
void print(){
sort(ans+1,ans+n,cmp1);
for(int i=1;i<n;i++)
printf("%d %d\n",ans[i].fir>m?ans[i].fir-m:ans[i].fir,ans[i].sec);
}
int find(int x){return p[x]==x?p[x]:p[x]=find(p[x]);}
bool check(int nowk,int tmp){
memset(st,0,sizeof(st));
for(int i=1;i<M-10;i++) p[i]=i;
int res=0,cnt=0,x,y,w1;tt=0;
for(int i=1;i<=m;i++){
if(cnt==k) break;
x=edges1[i].x;y=edges1[i].y;w1=edges1[i].w;
int pa=find(x),pb=find(y);
if(pa!=pb&&cnt<k&&w1<=nowk){
p[pa]=pb;
st[nowp]=true;
res+=w1;
cnt++;
ans[++tt]={nowp,1};
}
}
if(cnt!=k) return false;
for(int i=1;i<=m1;i++){
if(cnt==n-1) break;
x=edges2[i].x;y=edges2[i].y;w1=edges2[i].w;
int pa=find(x),pb=find(y);
if(!st[edges2[i].num]&&pa!=pb&&w1<=nowk){
p[pa]=pb;
res+=w1;
cnt++;
ans[++tt]={edges2[i].num,edges2[i].kd};
}
}
int last=-1;
for(int i=1;i<=n;i++){
int j=find(i);
if(last!=-1&&last!=j) return false;
last=j;
}//这块判断了一下求完最小生成树后是否连通
if(tmp) print();
return (cnt==n-1);
}
int main(){
scanf("%d%d%d",&n,&k,&m);
m1=m*2;int x,y,w1,w2,L=inf,R=0;
for(int i=1;i<M-10;i++) p[i]=i;
for(int i=1;i<=m;i++){
scanf("%d%d%d%d",&x,&y,&w1,&w2);
edges1[i]={x,y,w1,i,1};//一级
edges2[i]={x,y,w1,i,1};
edges2[i+m]={x,y,w2,i,2};//二级+一级
R=max(R,max(w1,w2));
L=min(L,min(w1,w2));
}
sort(edges1+1,edges1+m+1,cmp);
sort(edges2+1,edges2+m1+1,cmp);
while(L<R){
int mid=L+R>>1;
if(check(mid,0)) R=mid;
else L=mid+1;
}
printf("%d\n",R);
bool tmp=check(R,1);
return 0;
}