用最小生成树中的Kruskal算法解决。
代码如下:
#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
const int maxn=1e4+5;
struct E
{
int f,t;
int wei;
}edge[maxn];
int fa[105];
bool cmp(E x, E y)
{
return x.wei<y.wei;
}
void init()
{
for(int i=0;i<105;i++)
fa[i]=i;
}
int find(int x)
{
if(x==fa[x])
return x;
return find(fa[x]);
}
void unite(int x,int y)
{
x=find(x),y=find(y);
if(x!=y)
fa[x]=y;
}
int Kruskal(int num)
{
int sum=0;
for(int i=0;i<num;i++)
{
int a=find(edge[i].f),b=find(edge[i].t);
if(a!=b)
{
sum+=edge[i].wei;
fa[a]=b;
}
}
return sum;
}
int main()
{
int n;
while(~scanf("%d",&n)&&n)
{
int num=(n-1)*n/2;
int cnt=0;
init();
for(int i=1;i<=num;i++)
{
int a,b,c,d;
scanf("%d%d%d%d",&a,&b,&c,&d);
if(a>b) swap(a,b);
if(d)
unite(a,b);
else
{
edge[cnt].f=a;
edge[cnt].t=b;
edge[cnt++].wei=c;
}
}
sort(edge,edge+cnt,cmp);
printf("%d\n",Kruskal(cnt));
}
return 0;
}