题目来源:HDU 1879
简单思路:
补了一道好久之前的题,最小生成树,只不过这道题里面可能有已经连好的一部分边,将这些边的权值设为0即可,因为本来就已经连好,不需要任何花费。然后就是Kruskal求MST就好了。
#include <iostream>
#include <cstdio>
#include <string.h>
#include <algorithm>
#define loop(i,n) for(int i=1;i<=(n);++i)
using namespace std;
const int MAXN=5000+5;
int pre[105];
struct kru
{
int src,dest,w,vis;
}temp[MAXN];
int findR(int x)
{
while(x!=pre[x])
x=pre[x];
return x;
}
bool cmp(kru a,kru b)
{
return a.w<b.w;
}
int main()
{
int N;
while(~scanf("%d",&N)&&N!=0)
{
int cnt=0,ans=0;
int edge=N*(N-1)/2;
loop(i,N)
pre[i]=i;
loop(i,edge)
{
scanf("%d%d%d%d",&temp[i].src,&temp[i].dest,&temp[i].w,&temp[i].vis);
if(temp[i].vis)
temp[i].w=0;
}
sort(temp+1,temp+1+edge,cmp);
loop(i,edge)
{
int xx=findR(temp[i].src);
int yy=findR(temp[i].dest);
if(xx!=yy)
{
pre[yy]=xx;
cnt++;
ans+=temp[i].w;
}
if(cnt==N-1)
break;
}
printf("%d\n",ans);
}
return 0;
}