问题链接:。
问题简述:输入n和m,分别表示城镇的数量和城镇间道路的数量。再输入m个数对s和d表示城镇s到d有道路连通。问还需要修多少条道路才能够把这些城镇都连通起来。
问题分析:这是一个有关图的连通性问题,可以用并查集来解决。并查集中,连通的各个结点都会指向相同的根。
程序说明:程序中,构建一个用并查集,使得相互连通的子图指向相同的根,发现到两个互不相连的子图时,增加一条边使之相连。
AC的程序如下:
/* HDU1232 畅通工程 */#include#include using namespace std;// 并查集类class UF {private: vector v;public: UF(int n) { for(int i=0; i<=n; i++) v.push_back(i); } int Find(int x) { for(;;) { if(v[x] != x) x = v[x]; else return x; } } bool Union(int x, int y) { x = Find(x); y = Find(y); if(x == y) return false; else { v[x] = y; return true; } }};int main(){ int n, m, src, dest, root, count; while(cin >> n && n != 0) { UF uf(n); cin >> m; // 输入边(城镇道路),构造并查集 while(m--) { cin >> src >> dest; if(uf.Find(src) != uf.Find(dest)) uf.Union(src, dest); } // 逐个结点(城镇)检查是否联通,如果不联通则修一条道路使其联通 count = 0; root = uf.Find(1); for(int i=2; i<=n; i++) if(uf.Find(i) != root) { uf.Union(i, 1); count++; } // 输出结果 cout << count << endl; } return 0;}