usaco2016open silver3 closing

来源:互联网 发布:蒋勤勤的长相知乎 编辑:程序博客网 时间:2024/05/19 01:32

Sliver3

【题目描述】

FJ和他的奶牛们正在计划离开小镇做一次长的旅行,同时FJ想临时地关掉他的农场以节省一些金钱。

 

这个农场一共有被用M条双向道路连接的N个谷仓(1<=N,M<=3000)。为了关闭整个农场,FJ 计划每一次关闭掉一个谷仓。当一个谷仓被关闭了,所有的连接到这个谷仓的道路都会被关闭,而且再也不能够被使用。

 

FJ现在正感兴趣于知道在每一个时间(这里的“时间”指在每一次关闭谷仓之后的时间)时他的农场是否是“全连通的”——也就是说从任意的一个开着的谷仓开始,能够到达另外的一个谷仓。注意自从某一个时间之后,可能整个农场都开始不会是“全连通的”。

 

【输入格式】

输入的第一行是N和M。下面的M行每行都描述了一条连接两个谷仓的双向路径的两个端点(输入的点保证在1...N的范围内),最后的N行是一个1...N的排列,描述每一个谷仓被关闭的顺序。

 

【输出顺序】

输出一共有N行,每行可以是“YES”或者“NO”。第一行表示一开始时整个农场是否是“全连通的”,然后第i+1行表示在第i次的关闭谷仓之后整个农场是否是“全连通的”。

 

【样例输入】

4 3

1 2

2 3

3 4

3

4

1

2

 

 

【样例输出】

YES
NO
YES
YES

================================================================

显而易见,这道题是典型的图论题.稍稍进行转换就可以变成一个无向图的模型:m 双向道m 条无向边,n 谷仓则是 n 个顶点.每次删除一个顶点,问整个图是否连通.而要判断图是否连通,最方便的办法就是利用高效的数据结构----并查集.但是,还有但是!题目是不断删除点,这就不好实现了.不过我们可以先把删除的点先全部读进来,然后逆向地进行操作,把不断删除点变成不断增加点即可.

#include <fstream>
#include <iostream>

using namespace std;

const int SIZE = (3000 + 5);

ifstream fin("closing.in");
ofstream fout("closing.out");

int N, M, vertex[SIZE], father[SIZE];
bool graph[SIZE][SIZE], ans[SIZE], visited[SIZE];

int Find(int);
void Union(int, int);

int main() {
fin >> N >> M;

for(int i = 1; i != N + 1; ++i) {
father[i] = i;
}

for(int i = 0; i != M; ++i) {
int u, v;
fin >> u >> v;
graph[u][v] = graph[v][u] = true;
}

for(int i = N - 1; i != -1; --i) {
fin >> vertex[i];
}

for(int i = 0; i != N; ++i) {
visited[vertex[i]] = true;
int father1, father2;

for(int j = 1; j != N + 1; ++j) {
father1 = Find(vertex[i]);

if(j != vertex[i] && graph[vertex[i]][j] && visited[j]) {
father2 = Find(j);
Union(father1, father2);
}
}

ans[i] = true;

for(int j = 1; j != N + 1 && ans[i]; ++j) {
father1 = Find(vertex[i]);
father2 = Find(j);

if(visited[j] && father1 != father2) {
ans[i] = false;
}
}
}

for(int i = N - 1; i != -1; --i) {
fout << (ans[i] ? "YES" : "NO") << endl;
}

return 0;
}

int Find(int root) {
return (father[root] == root ? root : father[root] = Find(father[root]));
}

void Union(int f1, int f2) {
if(f1 != f2) {
father[f2] = f1;
}
}

0 0
原创粉丝点击