1 条题解

  • 1
    @ 2023-7-8 15:45:18
    
    
    #include<bits/stdc++.h>
    using namespace std;
    int s[1000010];
    int n,m,need;
    struct node{
    	int s,t,w,c;
    }e[1000010];
    inline bool cmp(node a,node b){
    	if(a.w==b.w) return a.c<b.c;
    	else return a.w<b.w;
    }
    inline int find(int x){
    	if(s[x]==x) return x;
    	return s[x]=find(s[x]);
    }
    int sum,ans,temp;
    int cnt=0;
    inline void kruskal(){
    	sort(e+1,e+1+m,cmp);
    	for(int i=1;cnt!=n-1;i++){
    		int xx=find(e[i].s),yy=find(e[i].t);
    		if(xx==yy) continue;
    		if(xx!=yy){
    			cnt++;
    			s[xx]=yy;
    			if(e[i].c==0) temp++;
    			sum+=e[i].w;
    		} 
    	}
    }
    int main(){
    	scanf("%d%d%d",&n,&m,&need);
    	for(int i=1;i<=m;i++){
    		scanf("%d%d%d%d",&e[i].s,&e[i].t,&e[i].w,&e[i].c);
    		e[i].s++;
    		e[i].t++;
    	}
    	int l=-111,r=111;
    	while(l<=r){
    		int mid=(l+r)>>1;
    		for(int i=1;i<=m;i++){
    			if(e[i].c==0){
    				e[i].w+=mid;
    			}
    		}
    		for(int i=1;i<=n+1;i++){
    			s[i]=i;
    		}
    		sum=0;
    		cnt=0;
    		temp=0;
    		kruskal();
    		if(temp>=need){
    			l=mid+1;
    			ans=sum-need*mid;
    		}
    		else r=mid-1;
    		for(int i=1;i<=m;i++){
    			if(e[i].c==0){
    				e[i].w-=mid;
    			}
    		}	
    	}
    	printf("%d\n",ans);
    	return 0;
    }
    

    二分答案加最小生成树

    `

    信息

    ID
    1324
    时间
    1000ms
    内存
    512MiB
    难度
    10
    标签
    递交数
    2
    已通过
    2
    上传者