您的位置:首页 > 其它

HDU~1879~继续畅通工程

2014-12-09 14:52 267 查看
和前几个最小生成树有点不一样的地方就是:

在kruskal里面,要先把已经修通的路排在前面(不知道这样是不是多此一举呢),再按照每条路的价值从小到大排序

自定义排序规则就是(调用C++的sort):

int cmp(const E a,const E b)
{
if(a.flag==b.flag)
return a.val<b.val;
return a.flag>b.flag;
}
将每条边存在结构体edge里面

struct E
{
int u,v,val;
int flag;
}edge[maxn];


主程序:

/*
* Author: 风凌月影
* School: HZIEE
* Time : 2005-06-02-02.42
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn= 5005;
int n,m;
int fa[105];
struct E { int u,v,val; int flag; }edge[maxn];
int cmp(const E a,const E b) { if(a.flag==b.flag) return a.val<b.val; return a.flag>b.flag; }
int findx(int x)
{
return x==fa[x]?x:fa[x]=findx(fa[x]);
}
int kruskal()
{
int ans=0;
for(int i=0;i<=n;i++)
fa[i]=i;
sort(edge,edge+m,cmp);
for(int i=0;i<m;i++)
{
int fu=findx(edge[i].u);
int fv=findx(edge[i].v);
if(edge[i].flag)
{
fa[fv]=fu;
}
if(fu!=fv)
{
if(!edge[i].flag)
{
ans+=edge[i].val;
}
fa[fv]=fu;
}
}
return ans;
}
int main()
{
while(scanf("%d",&n)&&n)
{
m=n*(n-1)/2;
for(int i=0;i<m;i++)
{
scanf("%d %d %d %d",&edge[i].u,&edge[i].v,&edge[i].val,&edge[i].flag);

}
printf("%d\n",kruskal());
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: