畅通道路
放图祭命运共同体
祭祀完毕!
下面来看这道题。
这输入方式……不明摆着让我们用kruscal吗?
只是这道题与之前两道不一样的地方是,有部分道路是事先修好的。
那么我们就稍微变通一下即可。
我们回想一下,我们怎么记录生成树的?并查集!
所以我们只需要在读入时,把现成的边在并查集中连在一起即可,剩下的这个边就可以直接扔掉,不需要放在kruscal的排序序列中。剩下的按kruscal做一遍即可。
每加一条边,把边权加在最终结果即可。
代码如下:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct edge{
int u,v,w;
};
int cmp(edge a,edge b){
return a.w<b.w;
}
int n,m;
edge e[10005];
int p[105];
int ans;
int find(int cur){
return cur==p[cur]?cur:p[cur]=find(p[cur]);
}
void work(){
ans=0;
sort(e,e+m,cmp);
for(int i=0;i<m;i++){
int x=find(e[i].u),y=find(e[i].v);
if(x!=y){
p[x]=y;
ans+=e[i].w;
}
}
}
int main(){
while(1){
scanf("%d",&n);
if(n==0){
break;
}
for(int i=1;i<=n;i++){
p[i]=i;
}
m=0;
for(int i=0;i<n*(n-1)/2;i++){
int u,v,w,vis;
scanf("%d%d%d%d",&u,&v,&w,&vis);
if(vis){
p[find(u)]=find(v);
}else{
e[m].u=u;
e[m].v=v;
e[m].w=w;
m++;
}
}
work();
printf("%d\n",ans);
}
return 0;
}
PS:这两天在忙着填志愿,可能做题比较少,以后会加大题量的。