hdu 1879 继续畅通工程
主要思路就是先把已存在的道路用并查集并起来,再将排序后的且不存在的边遍历一遍,若边的两顶点不在一个集合内,则将两顶点并起来且将费用cost加上该边的权值
另外在网上看到另一种好的思路就是将已存在的边的权值置为0,然后进直接用最小生成树算法
#include <stdio.h>
#include <iostream>
#include <algorithm>
using namespace std;
int p[105],n,m;
struct edge
{
int u,v,w;
int flag;
}ed[5000];
int get(int x)
{
if(p[x]==x)
return x;
else
return p[x]=get(p[x]);
}
void uni(int x,int y)
{
int a,b;
a=get(x);
b=get(y);
p[a]=b;
}
bool cmp(edge a, edge b) {
return a.w < b.w;
}
int main()
{
int i,x,y,cost;
while(1)
{
scanf("%d",&n);
if(n==0)
break;
cost=0;
m=n*(n-1)/2;
for(i=1;i<=n;i++)
p[i]=i;
for(i=0;i<m;i++)
scanf("%d%d%d%d",&ed[i].u,&ed[i].v,&ed[i].w,&ed[i].flag);
sort(ed, ed+m, cmp);
for(i=0;i<m;i++)
{
if(ed[i].flag==1)
{
x=ed[i].u;
y=ed[i].v;
if(get(x)!=get(y))
uni(x,y);
}
}
for(i=0;i<m;i++)
{
if(ed[i].flag==0)
{
x=ed[i].u;
y=ed[i].v;
if(get(x)!=get(y))
{
uni(x,y);
cost+=ed[i].w;
}
}
}
printf("%d\n",cost);
}
return 0;
}

浙公网安备 33010602011771号