您的位置:首页 > 其它

HDU 1272 小希的迷宫 【并查集好题】

2018-02-27 11:36 225 查看
传送门

// 题意: 问给定的一幅图是否任意两点之间有且仅有一条路径.

思路: 首先一种比较笨的方法就是先并查集维护联通性, 然后用dfs判断图是否有环, 比较麻烦, 但是也能过., 当然最好的方法就是用并查集也可以判环, 当然你的并查集是用了启发式合并的, 所以我们就有每个点的所在集合的size, 图中有环是什么情况了, 也就是某个点的size或翻一倍, 也就是最终的点的size不可能刚好等于总点数, 所以扫一遍判断一下就OK啦…

这是因为我们连接的两个点并没有去管他们是否是在同一个集合中, 但是题目是不允许的, 所以我们可以根据这个点来判断是否符合题意!…..

AC Code

const int maxn = 1e5 + 5;
int fa[maxn], r[maxn];
int a[maxn], vis[maxn];
void init(int n) {
for(int i = 1 ; i<= n ; i++){
fa[i] = i;
r[i] = 1;
}
Fill(vis, 0);
}
int Find(int x) {
return fa[x] == x ? x : fa[x] = Find(fa[x]);
}
void Un(int x, int y) {
x = Find(x), y = Find(y);
if(r[x] < r[y])
swap(x, y);
fa[y] = x;
r[x] += r[y];
}
void solve()
{
int u, v;
while(scanf("%d%d", &u, &v)) {
init(maxn-5);
if (!u && !v) {
printf("Yes\n");
continue;
}
if (u == -1 && v == -1) break;
int sum = 0, k = 0;
if (!vis[u]) sum++, a[++k] = u;
if (!vis[v]) sum++, a[++k] = v;
vis[u] = vis[v] = 1;
u = Find(u); v = Find(v);
Un(u, v);
while(~scanf("%d%d", &u, &v)) {
if (u + v == 0) break;
if (!vis[u]) sum++, a[++k] = u;
if (!vis[v]) sum++, a[++k] = v;
vis[u] = vis[v] = 1;
u = Find(u); v = Find(v);
Un(u, v);
}
int flag = 0;
for (int i = 1 ; i <= k ; i ++) {
if (r[a[i]] == sum) {
flag = 1;
break;
}
}
if (!flag) printf("No\n");
else printf("Yes\n");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: