用Boruvka只过了两个点,求助大佬
查看原帖
用Boruvka只过了两个点,求助大佬
669680
faint楼主2022/8/4 09:12

只过了最后两个点

#include<bits/stdc++.h>
#define re register
#define M 200005
#define N 100005
using namespace std;
int n,k,m,ans[M],f[N],maxx=INT_MIN,best[N],cnt;
bool vis[M];
struct nd { int a,b,c1,c2; }edge[M];
int find(int u){ return u==f[u] ? u:find(f[u]); }
void hb(int u,int v){ f[find(u)]=find(v); }
bool btr(int u,int v){
	if(v==0) return 1;
	if(cnt<k){
		if(edge[u].c1!=edge[v].c1) return edge[u].c1<=edge[v].c1;
		return u<v;
	}
	else{
		if(edge[u].c2!=edge[v].c2) return edge[u].c2<edge[v].c2;
		return u<v;
	}
}
void boruvka(){
	while(1){
		memset(best,0,sizeof(best));
		for(re int i=1;i<=m-1;i++){
			if(!vis[i]){
				int uu=find(edge[i].a),vv=find(edge[i].b);
				if(uu==vv) continue;
				if(btr(i,best[uu])) best[uu]=i;
				if(btr(i,best[vv])) best[vv]=i;
			}
		}
		for(re int i=1;i<=n;i++){
			if(best[i]&&!vis[best[i]]){
				cnt++;
				vis[best[i]]=1;
				hb(edge[best[i]].a,edge[best[i]].b);
				if(cnt<=k){
					maxx=max(maxx,edge[best[i]].c1);
					ans[best[i]]=1;
				}
				else{
					maxx=max(maxx,edge[best[i]].c2);
					ans[best[i]]=2;
				}
			}
		}
		if(cnt==n-1) break;
	}
}
int main(){
	ios::sync_with_stdio(0);
	cin>>n>>k>>m;
	for(re int i=1;i<=m-1;i++) cin>>edge[i].a>>edge[i].b>>edge[i].c1>>edge[i].c2;
	for(re int i=1;i<=n;i++) f[i]=i;
	boruvka();
	cout<<maxx<<'\n';
	for(int i=1;i<=m;i++){
		if(ans[i]==0) continue;
		cout<<i<<' '<<ans[i]<<'\n';
	}
	return 0;
}
2022/8/4 09:12
加载中...