利用并查集做
设某个要计算的点为p
然后对与p连接的那些点做深度搜索,然后在dfs中对他们经行合并操作。
最后判断祖先的数量有多少,若>1,则有几个祖先就说明有几个不一样的子集,也就是不能互相访问的子网。
#include#include #include #include #include #include #include #include using namespace std; vector
map[1001]; int anc[1001]; int maxn = 0; int vis[1001]; int val[1001]; int temp[1001]; void init() { for (int i = 0; i <= maxn; i++) { map[i].clear(); } maxn = 0; } int Find(int id) { return (anc[id] == id) ? id : (anc[id] = Find(anc[id])); } void unio(int p1, int p2) { int fp1 = Find(p1); int fp2 = Find(p2); if (val[fp1] > val[fp2]) { anc[p2] = fp1; val[fp1] += val[fp2]; } else { anc[p1] = fp2; val[fp2] += val[fp1]; } } void dfs(int id) { vector nd = map[id]; for (int i = 0; i < nd.size(); i++) { if (!vis[nd[i]]) { vis[nd[i]] = 1; unio(id, nd[i]); dfs(nd[i]); } } } int main() { int u, v, cur; cur = 0; while (cin >> u) { if (!u) break; if(cur){ cout << endl; } cin >> v; init(); map[u].push_back(v); map[v].push_back(u); maxn = max(maxn, max(u, v)); while (cin >> u) { if (!u) break; cin >> v; map[u].push_back(v); map[v].push_back(u); maxn = max(maxn, max(u, v)); } printf("Network #%dn", ++cur); int flag=0; for (int i = 1; i <= maxn; i++) { vector roots = map[i]; memset(vis, 0, sizeof(vis)); memset(temp, 0, sizeof(temp)); //初始化 for (int i = 1; i <= maxn; i++) { anc[i] = i; val[i] = 1; } vis[i] = 1; for (int j = 0; j < roots.size(); j++) { if (vis[roots[j]])continue; vis[roots[j]] = 1; dfs(roots[j]); } int res = 0; for (int j = 0; j < roots.size(); j++) { int fa = Find(roots[j]); if (!temp[fa]) { res++; temp[fa] = 1; } } // printf("forbid i:%dn", i); // for (int j = 1; j <= maxn; j++) { // cout << j << "anc:" << anc[j] << endl; // } if (res > 1) { printf(" SPF node %d leaves %d subnetsn", i, res); flag=1; } } if(!flag){ cout << " No SPF nodes"<



