WQS二分求助(赏关x1)
查看原帖
WQS二分求助(赏关x1)
275989
LingHusama楼主2023/9/11 09:40

40pts不知道问题何在。

因为已经调了1d了

所以悬赏关注x1

感谢各位大佬于百忙中抽出时间看我的问题代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
/*
不考虑need,就是最小生成树 
本题是一个下凸函数 
*/
struct node{
	int s;
	int t;
	int c;
	int col;
}line[100005];
bool cmp(node x,node y){
	if(x.c!=y.c)return x.c<y.c;
	else return x.col<y.col;
}
int fa[100005];
int n,m,need;
int finda(int x){
	if(fa[x]==x){
		return x;
	}
	else{
		fa[x]=finda(fa[x]);
		return fa[x];
	}
} 
void unite(int x,int y){
	x=finda(x);
	y=finda(y);
	if(x==y){
		return;
	}
	else{
		fa[x]=y;
	}
}
bool judge(int x,int y){
	x=finda(x);
	y=finda(y);
	if(x==y){
		return 1; 
	}
	else{
		return 0;
	}
}
int gb;
int gx;
void check(int cc){
	gx=0;
	gb=0;
	for(int i=0;i<=n;i++){
		fa[i]=i;
	}
	for(int i=1;i<=m;i++){
		if(line[i].col==0){
            //cout<<"ptest:"<<line[i].c<<endl;
			line[i].c-=cc;//相对顺序会改变 
            //cout<<"ltest:"<<line[i].c<<endl;
		}
	}
	sort(line+1,line+1+m,cmp);
	for(int i=1;i<=m;i++){
		if(judge(line[i].s,line[i].t)==1){
			continue;
		}
		else{
			unite(line[i].s,line[i].t);
			gb+=line[i].c;
			if(line[i].col==0){
				gx++;
			}
		}
	}
	//跑一次最小生成树 
	for(int i=1;i<=m;i++){
		if(line[i].col==0)
		line[i].c+=cc;
	}
}
signed main(){
	ios::sync_with_stdio(false);
	cin >> n >> m >> need;
	for(int i=1;i<=m;i++){
		cin >> line[i].s >> line[i].t >> line[i].c >> line[i].col;
	}
	int l=-1e13;
	int r=1e13;
	for(int i=1;i<=200;i++){
		int mid=1.0*(l+r)/2;
		check(mid);
		if(gx<need){
			l=mid+1;
			
		}
		else{
			r=mid;
		}
	}
	int pron=(r);
	check(pron);
//	cout<<"TEST"<<r<<endl;
	cout<<(int)(pron*gx+gb);
}
2023/9/11 09:40
加载中...