洛谷 P3144 [USACO16OPEN]关闭农场Closing the Farm_Silver

传送门

题目大意:

n个谷仓 ,每次关闭一个谷仓,问剩下没被关闭的谷仓是

否联通。

题解:并查集+倒序处理

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#define N 3030
using namespace std;

int n,m,sumedge,cnt;

int head[N],fa[N],q[N],ans[N],exit[N];

struct Edge{
    int x,y,nxt;
    Edge(int x=0,int y=0,int nxt=0):
        x(x),y(y),nxt(nxt){}
}edge[N<<1];

void add(int x,int y){
    edge[++sumedge]=Edge(x,y,head[x]);
    head[x]=sumedge;
}

int f(int x){
    return fa[x]==x?x:fa[x]=f(fa[x]);
}

int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        add(x,y);add(y,x);
    }
    for(int i=1;i<=n;i++)fa[i]=i;cnt=n;
    for(int i=1;i<=n;i++)scanf("%d",&q[i]);
    for(int i=n;i>=1;i--){
        int x=q[i];exit[x]=true;
        for(int h=head[x];h;h=edge[h].nxt){
            int v=edge[h].y;
            if(exit[v]==0)continue;
            int fx=f(x),fy=f(v);
            if(fx!=fy){
                fa[fx]=fy;
                cnt--;
            }
        }
        if(cnt==i)ans[i]=true;
    }
    for(int i=1;i<=n;i++)
     if(ans[i])puts("YES");
     else puts("NO");
    return 0;
}
并查集
#include<iostream>
#include<cstdio>
#include<cstring>
#define N 3009
using namespace std;

int n,m,cnt;

int q[N],exit[N],ans[N],d[N][N];

int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        d[x][y]=d[y][x]=true;
    }
    for(int i=1;i<=n;i++)scanf("%d",&q[i]);
    for(int i=n;i>=1;i--){
        bool flag=false;
        int now=q[i];
        exit[++cnt]=now;
        for(int k=1;k<=cnt;k++){
            for(int j=1;j<=cnt;j++){
                for(int p=1;p<=cnt;p++){
                    d[exit[j]][exit[p]]=d[exit[j]][exit[p]]||(d[exit[j]][exit[k]]&&d[exit[k]][exit[p]]);
                }
            }
        }
        for(int j=1;j<=cnt;j++){
            for(int p=j+1;p<=cnt;p++){
                if(d[exit[j]][exit[p]]==0){
                    ans[i]=0;flag=true;
                    break;
                }
            }
        }
        if(flag==false){
            ans[i]=1;
        }
    }
    for(int i=1;i<=n;i++)
     if(ans[i])printf("YES
");
     else printf("NO
");
    return 0;
}
50暴力
原文地址:https://www.cnblogs.com/zzyh/p/7792582.html