博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【bzoj4579】[Usaco2016 Open]Closing the Farm 并查集
阅读量:5086 次
发布时间:2019-06-13

本文共 2539 字,大约阅读时间需要 8 分钟。

题目描述

Farmer John and his cows are planning to leave town for a long vacation, and so FJ wants to temporarily close down his farm to save money in the meantime.The farm consists of NN barns connected with MM bidirectional paths between some pairs of barns (1≤N,M≤200,000). To shut the farm down, FJ plans to close one barn at a time. When a barn closes, all paths adjacent to that barn also close, and can no longer be used.FJ is interested in knowing at each point in time (initially, and after each closing) whether his farm is "fully connected" -- meaning that it is possible to travel from any open barn to any other open barn along an appropriate series of paths. Since FJ's farm is initially in somewhat in a state of disrepair, it may not even start out fully connected.

输入

The first line of input contains N and M. The next M lines each describe a path in terms of the pair of barns it connects (barns are conveniently numbered 1…N). The final N lines give a permutation of 1…N describing the order in which the barns will be closed.

输出

The output consists of N lines, each containing "YES" or "NO". The first line indicates whether the initial farm is fully connected, and line i+1 indicates whether the farm is fully connected after the iith closing.

样例输入

4 3

1 2
2 3
3 4
3
4
1
2

样例输出

YES

NO
YES
YES


题目大意

给你n个点和m条边的无向图,有n次删点操作,删掉点后与这个点相连的边也随之删除。问删除每个点之前这个图是不是连通图。

题解

并查集

由于删点比较难搞,所以我们需要换一种思路:

可以先把所有的点删掉,然后反过来一个一个再加进来。

这样便于直接处理改动的边。

然后用一个并查集维护连通块即可。

#include 
int head[200010] , to[400010] , next[400010] , cnt , a[200010] , f[200010] , ans[200010] , ok[200010];int find(int x){ return x == f[x] ? x : f[x] = find(f[x]);}void add(int x , int y){ to[++cnt] = y; next[cnt] = head[x]; head[x] = cnt;}int main(){ int n , m , i , j , x , y , tmp = 0; scanf("%d%d" , &n , &m); for(i = 1 ; i <= m ; i ++ ) scanf("%d%d" , &x , &y) , add(x , y) , add(y , x); for(i = 1 ; i <= n ; i ++ ) scanf("%d" , &a[i]); for(i = 1 ; i <= n ; i ++ ) f[i] = i; for(i = n ; i >= 1 ; i -- ) { ok[a[i]] = 1; tmp ++ ; for(j = head[a[i]] ; j ; j = next[j]) { if(ok[to[j]]) { x = find(a[i]) , y = find(to[j]); if(x != y) { f[x] = y; tmp -- ; } } } ans[i] = (tmp == 1); } for(i = 1 ; i <= n ; i ++ ) printf("%s\n" , ans[i] ? "YES" : "NO"); return 0;}

转载于:https://www.cnblogs.com/GXZlegend/p/6435010.html

你可能感兴趣的文章
2015 Multi-University Training Contest 3
查看>>
使用Gitblit 在windows 上部署你的Git Server
查看>>
217. Contains Duplicate
查看>>
vue2.0 关于Vue实例的生命周期
查看>>
jenkins 更换主数据目录
查看>>
Silverlight中恼人的g.i.cs错误
查看>>
SQLite 数据库增删改查
查看>>
<s:iterator>的status
查看>>
C++入门--1.0输入输出
查看>>
让搭建在Github Pages上的Hexo博客可以被Google搜索到
查看>>
Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十四章:曲面细分阶段...
查看>>
在WPF控件上添加Windows窗口式调整大小行为
查看>>
背水一战 Windows 10 (36) - 控件(弹出类): ToolTip, Popup, PopupMenu
查看>>
打开3389
查看>>
React学习记录
查看>>
nginx常见内部参数,错误总结
查看>>
对象与类
查看>>
《奸的好人2》财色战场----笔记
查看>>
BZOJ 1834网络扩容题解
查看>>
bzoj1878
查看>>