[USACO16OPEN] Closing the Farm G - 洛谷
//转换+并查集 #include <bits/stdc++.h> #define int long long #define PII pair<int,int> #define ll long long #define endl '\n' using namespace std; const int N=2e5+10,M=5010; int dot[N],used[N]; //记住,如果是无向图要开双倍的边; 因为这个wa了很多次 int e[N*2],ne[N*2],h[N*2],idx; int p[N]; bool st[N]; void add(int a,int b) { e[idx]=b;ne[idx]=h[a];h[a]=idx++; } int find(int x) { if(x!=p[x]) { p[x]=find(p[x]); } return p[x]; } signed main() { cin.tie(0);cout.tie(0); ios::sync_with_stdio(0); int n,m;cin>>n>>m; memset(h,-1,sizeof h); for(int i=1;i<=m;i++) { int x,y;cin>>x>>y; add(x,y);add(y,x); } for(int i=1;i<=n;i++) { p[i]=i; cin>>dot[i]; } int sum=1;//最开始集合中只有一个点; for(int i=n;i>=1;i--) { //初始sum==0//sum++;当前一个点表示一个集合; int x=dot[i];used[x]=1;//标记为已经加入集合的点; int px=find(x); for(int j=h[x];j!=-1;j=ne[j]) { int y=e[j]; int py=find(y); //所以是p[py]=px;把所有的点连到新点中, //这样之前已经在集合中的点任一连到新点,那么就合并成功了 //如果是p[px]=py的话,那么就是把新点连到已知的点中, //就会造成有些点没有连接到新点;答案错误; if(px!=py&&used[y]) { p[py]=px; //如果是p[px]=py那么结果就错的; sum++;//sum--表示只有一个集合; } } //表示当前的集合中的点数,是否为这个; if(sum==n-i+1)st[i]=true; //if(sum==1)st[i]=true;表示只有一个集合; } for(int i=1;i<=n;i++) { if(st[i])cout<<"YES"<<endl; else cout<<"NO"<<endl; } return 0; }
P6121 [USACO16OPEN] Closing the Farm G
最新推荐文章于 2024-06-13 23:07:13 发布