玄关求条
查看原帖
玄关求条
615727
swz8438楼主2025/8/4 22:16
#include<bits/stdc++.h>
using namespace std;
#define N 51419
#define M 114514
struct edge
{
    int u,v,w,c;
}e[M];
int n,m,k;
int fa[N],rk[N];
void init(){
    for(int i=0;i<n;i++){
        fa[i]=i;
        rk[i]=1;
    }
}
int find(int x){
    if(x==fa[x]) return x;
    fa[x]=find(fa[x]);
    return fa[x];
}
void merge(int x,int y){
    x=find(x),y=find(y);
    if(x==y) return;
    if(rk[x]>rk[y]) swap(x,y);
    fa[x]=y;
    rk[y]+=rk[x];
}
int bias;
int ans,ccnt;
bool cmp(edge x,edge y){
    if(x.w+bias*(x.c==0)!=y.w+bias*(y.c==0))
        return x.w+bias*(x.c==0)<y.w+bias*(y.c==0);
    return x.c<y.c;
}
void kruskal(){
    init();
    sort(e+1,e+m+1,cmp);
    int ecnt=0;
    ans=0,ccnt=0;
    for(int i=1;i<=m && ecnt<n-1;i++){
        if(find(e[i].u)!=find(e[i].v)){
            merge(e[i].u,e[i].v);
            ans+=e[i].w+bias*(e[i].c==0);
            ccnt+=(e[i].c==0);
            ecnt++;
        }
    }
}
int main(){
    ios::sync_with_stdio(0);
    cin>>n>>m>>k;
    for(int i=1;i<=m;i++){
        cin>>e[i].u>>e[i].v>>e[i].w>>e[i].c;
    }
    int l=-114,r=114,mid;
    while (l<r)
    {
        mid=(l+r)/2;
        bias=mid;
        kruskal();
        if(ccnt>k){
            l=mid+1;
        }else if(ccnt<k){
            r=mid-1;
        }else{
            break;
        }
    }
    cout<<ans-bias*k<<endl;
    return 0;
}
2025/8/4 22:16
加载中...