http://acm.hdu.edu.cn/showproblem.php?pid=1879
#include <stdio.h>
#include <algorithm>
using namespace std;
struct Edge
{
int a,b;
int cost;
int tag; //标志是否已建成,tag=1,则成本就为0,优先考虑
}edge[5000];
int Tree[100];
bool cmp(Edge A,Edge B) //本题核心在于重写cmp函数
{
if (A.tag!=B.tag) //已建成的排序在前,优先选择该边
{
return A.tag>B.tag; //也就是tag=1的在前,tag=0时,再按cost排序
}
else
{
return A.cost<B.cost;
}
}
int findRoot(int x)
{
if (Tree[x]==-1)
{
return x;
}
else
{
int tmp=findRoot(Tree[x]);
Tree[x]=tmp;
return tmp;
}
}
int main()
{
int n,i,a,b;
while (scanf("%d",&n)!=EOF && n!=0)
{
for(i=1;i<=n*(n-1)/2;i++)
{
scanf("%d%d%d%d",&edge[i].a,&edge[i].b,&edge[i].cost,&edge[i].tag);
}
sort(edge+1,edge+1+n*(n-1)/2,cmp); //所有边排序,别写成村庄数n
for (i=1;i<=n;i++)
{
Tree[i]=-1;
}
int ans=0;
for (i=1;i<=n*(n-1)/2;i++)
{
a=findRoot(edge[i].a);
b=findRoot(edge[i].b);
if (a!=b)
{
Tree[a]=b;
if (edge[i].tag==0)
{
ans+=edge[i].cost;
}
}
}
printf("%d\n",ans);
}
return 0;
}