穿梭时间的画面的钟 从反方向 开始移动|

tmjyh09

园龄:3年2个月粉丝:1关注:3

[USACO16OPEN]Closing the Farm 题解

本题有两道一模一样的题目,改个数据范围即可 AC。

题目1 | 题目2

题意简述

给定一张无向图,每次删去一个点,问每次操作后图是否联通。

分析

判断图是否联通可以想到使用并查集来维护。但是并查集很难实现删除操作,那如何处理呢?

并查集的核心是“并”和“查”,既然题目要求每次删去一个点,那不如反过来想,倒序处理,把删点变成加点,这样处理起来就非常方便快捷了。

代码实现

#include <bits/stdc++.h>
using namespace std;
int n, m;
struct edge
{
int to, nxt;
}e[3005 << 1];
int head[3005];
int idx;
void link(int x, int y) {
e[++idx].to = y;
e[idx].nxt = head[x];
head[x] = idx;
}
int fa[3005];
int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
int del[3005];
int f[3005];
int main() {
cin >> n >> m;
for (int i = 1, x, y; i <= m; i++) {
cin >> x >> y;
link(x, y);
link(y, x);
}
for (int i = 1; i <= n; i++)cin >> del[i];
int cnt = 0;
for (int i = n; i >= 1; i--) {
int cur = del[i];
fa[cur] = cur;
cnt++;
for (int j = head[cur]; j; j = e[j].nxt) {
int v = e[j].to;
if (fa[v]) {
int x = find(v), y = find(cur);
if (x != y) {
fa[x] = y;
cnt--;
}
}
}
if (cnt == 1)f[i] = true;
}
for (int i = 1; i <= n; i++)puts(f[i] ? "YES" : "NO");
return 0;
}

练习

可以尝试做做 星球大战

本文作者:tmjyh09

本文链接:https://www.cnblogs.com/tmjyh09/p/15814357.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   tmjyh09  阅读(35)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起