#include <iostream>
#include <algorithm>
using namespace std;
#define MAX 10000
struct edge
{
int u,v;
int price,vis;
}Edge[MAX];
int n,m;
int ans[MAX];
bool cmp(edge x,edge y)
{
if(x.vis!=y.vis)
return x.vis<y.vis;
else
return x.price<y.price;
}
void init()
{
int i;
for(i=1;i<=n;i++)
{
ans[i]=i;
}
}
int find(int x)
{
if(x!=ans[x])
ans[x]=find(ans[x]);
return ans[x];
}
void Merge(int a,int b)
{
int tx=find(a);
int ty=find(b);
if(tx!=ty)
ans[tx]=ty;
}
void Kruskal()
{
sort(Edge+1,Edge+m+1,cmp);
int i,sum=0;
for(i=1;i<=m;i++)
{
int tx=find(Edge[i].u);
int ty=find(Edge[i].v);
if(tx!=ty && !Edge[i].vis)
{
sum+=Edge[i].price;
ans[tx]=ty;
}
}
cout<<sum<<endl;
}
int main()
{
while(scanf("%d",&n) && n!=0)
{
m=(n*(n-1))/2;
init();
int i;
for(i=1;i<=m;i++)
{
scanf("%d %d %d %d",&Edge[i].u,&Edge[i].v,&Edge[i].price,&Edge[i].vis);
if(Edge[i].vis==1)
Merge(Edge[i].u,Edge[i].v);
}
Kruskal();
}
return 0;
}
直接上代碼,需要注意的有幾點:
1.初始化。
2.排序,sort函數的使用。一定要排序,Kruskal關鍵就是在排序,而prim則是用一個頂點數組lowcast達到類似的排序效果。
3.這道題是和並查集連起來用了,因爲涉及到“已建”和“未建”兩種集合,如果是直接read Graph,初始狀態要麼就是都沒建,要麼就是都已建好(找出最短路),那就不需要用並查集,直接用MAP[MAX[[MAX[即可。