hdu 1863 畅通工程 (最小生成树)

来源:互联网 发布:nginx下载windows 编辑:程序博客网 时间:2024/06/06 00:53


解题思路:这道题做了两次,第一次做的时候还不知道有最小生成树这种东西,以为是最短路问题,就顺着思路想,不过并没有什么结果,当时误打误撞想出了一种这种问题的解法,就是每次选取能够让这棵树延长的最短的那一条边,不过鉴于算法复杂度过高就没有实现,后来学习了最小生成树算法,现在看来这道题就很直接了,就是一个裸的Kruskal算法。这个算法的核心就在于每次选取一条既不能使图形成回路又是最短的边,也就是一个并查集的过程。

代码:

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <functional>#define inf 0x3f3f3f3fusing namespace std;typedef struct P{    int point1;    int point2;    int val;}p;bool compare(p a,p b){    return a.val<=b.val;}p edge[10001];int city[105];int getcity(int point){    if(city[point] == point)    {        return point;    }    else    {        city[point] = getcity(city[point]);        return city[point];    }}bool connect(int point1,int point2){    int t1,t2;    t1 = getcity(point1);    t2 = getcity(point2);    if(t1!=t2)    {        city[t2] = t1;        return true;    }    return false;}int main(){    int n,m;    int i;    int cnt,sum;    while(cin>>n>>m && n)    {        cnt = 0,sum = 0;        for(i=0;i<n;i++)        {            cin>>edge[i].point1>>edge[i].point2>>edge[i].val;        }        sort(edge,edge+n,compare);        for(i=1;i<=m;i++)//特别注意这里的序号要从1开始,与题目要求保持一致,因为没注意这里WA了一次            city[i] = i;        for(i=0;i<n;i++)        {            if(connect(edge[i].point1,edge[i].point2))            {                cnt++;                sum += edge[i].val;            }            if(cnt==m-1)                break;        }        if(cnt!=m-1)            cout << '?' << endl;        else            cout << sum << endl;    }    return 0;}

0 0