Hdu1232畅通工程 解题报告

来源:互联网 发布:javascript for in循环 编辑:程序博客网 时间:2024/06/06 03:43

 并查集:将编号分别为1到n的n个对象划分为不相交集合,在每个集合中,选择其中某个元素代表所在集合。主要有两个操作:(1)合并两个集合,(2)查找某元素属于哪个集合。下面是利用并查集求解Hdu 1232 畅通工程(http://acm.hdu.edu.cn/showproblem.php?pid=1232),比用dfs,bfs搜索大大提高了时间效率。

#include <iostream>#include <vector>using namespace std;vector <int> parents;int findSet(int i)//if (parents[i]==i) then i is root;else if (parents[i]==j(j!=i)) then j is root.{int root=i;while(root != parents[root]) //after loop get root{root=parents[root];}int k=i;while(k != root) //path compression{int t=parents[k];parents[k]=root;k=t;}    return root;}void unionSet(int a, int b)//union a,b to the small parent{int j=findSet(a);int k=findSet(b);if (j==k) return;if (j<k){parents[k]=j;}else{parents[j]=k;}}bool run(){    int n,m,i;    cin>>n;if (n==0) return false;cin>>m;parents.resize(n+1);for(i=1;i<=n;i++){parents[i]=i; //init ,each i is a tree}    for(i=0;i<m;i++)    {        int a,b;       cin>>a>>b;unionSet(a,b);    }int cntRoot=0;for(i=1;i<=n;i++){if (i==parents[i]) //count subtrees{cntRoot++;}}cout << cntRoot-1 << endl;return true;}int main(){while(run());return 0;}

 说明:while(k != root) //把i开始结点的根修改为找到的根root,路径压缩便于提高效率 

原创粉丝点击