bzoj4579: [Usaco2016 Open]Closing the Farm
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 24 Solved: 17
[Submit][Status][Discuss]
Description
Farmer John and his cows are planning to leave town for a long vacation, and so FJ wants to temporar
ily close down his farm to save money in the meantime.The farm consists of NN barns connected with M
M 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 ca
n no longer be used.FJ is interested in knowing at each point in time (initially, and after each clo
sing) whether his farm is "fully connected" -- meaning that it is possible to travel from any open b
arn to any other open barn along an appropriate series of paths. Since FJ‘s farm is initially in som
ewhat in a state of disrepair, it may not even start out fully connected.
Input
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 o
f 1…N describing the order in which the barns will be closed.
Output
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 th
e iith closing.
Sample Input
4 3
1 2
2 3
3 4
3
4
1
2
Sample Output
YES
NO
YES
YES
HINT
Source
直接在线的话lct似乎是可以做的?
然而可以离线。。。所以就变成傻逼题了。。。
离线后倒过来加边 并查集维护一下联通块个数即可
#include<bits/stdc++.h> #define rep(i,l,r) for(int i=l;i<=r;i++) #define N 500000 using namespace std; struct E{ int to,next; }e[N]; int n,m,out[N],f[N],tot,s[N],flag[N],head[N]; inline int read() { register int x=0,ch=getchar(); while(ch<‘0‘||ch>‘9‘) ch=getchar(); while(ch>=‘0‘&&ch<=‘9‘) x=x*10+ch-48,ch=getchar(); return x; } int find(int x) { if(f[x]==x) return x;else return f[x]=find(f[x]); } inline void ins(int u,int v) { e[++tot].to=v; e[tot].next=head[u]; head[u]=tot; } int main () { register int a,b,cnt,x,y; scanf("%d%d",&n,&m); rep(i,1,m) {a=read(); b=read(); ins(a,b); ins(b,a);} rep(i,1,n) s[i]=read(),flag[s[i]]=1,f[i]=i; cnt=n; rep(i,1,n) if(!flag[i]){ for(register int k=head[i];k;k=e[k].next) { if(!flag[e[k].to]) { x=find(i); y=find(e[k].to); if(x!=y) f[x]=y,--cnt; } } } for(register int i=n;i;i--) { flag[s[i]]=0; for(register int k=head[s[i]];k;k=e[k].next) if(!flag[e[k].to]) { x=find(s[i]); y=find(e[k].to); if(x!=y) f[x]=y,--cnt; } out[i]=(cnt==i); } rep(i,1,n) if(!out[i]) puts("NO");else puts("YES"); }