您的位置:首页 > 其它

组织集体活动

2016-03-22 00:37 232 查看
题目链接:http://acm.njupt.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=1081

直接套用克鲁斯卡尔算法模板



#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
#define N 1000
struct graph
{
int u,v,cost;  //顶点u和顶点V的边权是cost
void set(int a,int b,int w){u=a,v=b,cost=w;}
};

graph d[N*(N+1)/2];  //对于有n个顶点的图,边的数量是e<=n(n+1)/2

int father
;
int Find(int x)
{
if (father[x]==-1) return x;
return father[x] = Find(father[x]);
}

bool Union(int x, int y)
{  //判断两元素是否属于同一个集合,只要看看他们所在的集合的祖先是否相同
x = Find(x);
y = Find(y);
//祖先相同,是一个集合
if (x==y) return false;
//祖先不同,合并两个集合
if (x>y) father[x] = y;
if (x<y) father[y] = x;
return true;
}
//按照边权的递增顺序排序
int cmp(graph x,graph y)
{
if (x.cost<y.cost) return true;
return false;
}

int main()
{
int n, m;
while (scanf("%d%d", &n, &m)!=EOF && n)
{
int i;
int v,w,edge;
//假设有m条边,每条边描述是(v,w,edge)表示顶点v到顶点w的边权是edge,则构造边集合d如下:
for (i=0; i<m; i++)
{
scanf("%d%d%d", &v, &w, &edge);
d[i].set(v,w,edge);
}
sort(d, d+m, cmp);
memset(father, -1, sizeof(father));
int sum=0;  //最小生成树中边权的和
int count=0;
//查找每一条边
for(i=0; i<n*(n+1)/2; i++)
{
//找到一条满足的边
if (Union(d[i].u, d[i].v))
{
//  printf("%d %d\n", d[i].u, d[i].v);
sum += d[i].cost;
++count;
}
if (count==n-1)
break;
else
{
cout<<"Impossible"<<endl;
return 0;
}
}
printf("%d\n",sum);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: