HDU 1863

来源:互联网 发布:oracle awr sql 编辑:程序博客网 时间:2024/04/30 05:38

http://acm.hdu.edu.cn/showproblem.php?pid=1863

本人并查集专题:http://blog.csdn.net/fsafs168/article/details/7801010

/* * 并查集+贪心。 * 思路:这个问题首先要确定花费是最少的,所以把所有路都拿来,从小到大排序。 * 然后,我们又要确定是联通的,这个用到并查集来确定 * 每一次两个点只要连进去就不连了,同时是从小到大连的。 * 之后确定有多少块,一判断,一输出。0ms瞬秒 */#include <iostream>#include <cstdio>#include <algorithm>using namespace std;int father[110];struct Node{    int a;    int b;    int cost;}a[10000];bool cmp(Node a, Node b){    return a.cost<b.cost;}void ini(int n){    for(int i=0;i<=n;i++)        father[i] = i;}int find(int x){    if(x != father[x])        return find(father[x]);    return father[x];}void sert(int a, int b){    father[a] = b;}int main(){    int n,m,i,j;    while(scanf("%d%d",&n,&m)!=EOF&&n)    {        ini(m);        for(i=0;i<n;i++)        {            scanf("%d%d%d",&a[i].a,&a[i].b,&a[i].cost);        }        sort(a,a+n,cmp);        int sum = 0;        for(i=0;i<n;i++)        {            int aa,b;            aa = find(a[i].a);    //找根节点            b = find(a[i].b);    //找根节点            if(aa!=b)            {                sert(aa,b);                sum += a[i].cost;            }        }        int temp = -1;   //肯定是-1啦,因为至少有一块地方么        for(i=1;i<=m;i++)        {            if(i == find(i))    //有多少根节点                temp++;        }        //printf("temp:%d\n",temp);        if(!temp)   //明显说明,只有一块地方才行            printf("%d\n",sum);        else            printf("?\n");    }    return 0;}

原创粉丝点击