bzoj 4579: [Usaco2016 Open]Closing the Farm

4579: [Usaco2016 Open]Closing the Farm

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

题解:

首先这道题目什么意思呢???

大概是讲用m条边连接的农场,每次关闭一个谷仓,问你每次在关闭谷仓之前整个农场是否完全联通。

知道意思后这就是到很裸的并查集了,维护联通块个数,看看是不是1就行了。。。

#include<stdio.h>
#include<iostream>
using namespace std;
const int N=200005;
int n,m,i,j,x,y,fx,fy,cnt,a[N],p[N],ans[N],f[N];
int tot,head[N],Next[N<<1],to[N<<1];
void add(int x,int y)
{
    tot++;
    to[tot]=y;
    Next[tot]=head[x];
    head[x]=tot;
}
int get(int x)
{
    if(f[x]==x) return x;else return f[x]=get(f[x]);
}
int main()
{
    scanf("%d%d",&n,&m);
    for(i=1;i<=n;i++)
        head[i]=-1;
    for(i=1;i<=m;i++)
    {
        scanf("%d%d",&x,&y);
        add(x,y);
        add(y,x);
    }
    for(i=1;i<=n;i++)
        f[i]=i;
    for(i=1;i<=n;i++)
        scanf("%d",&a[i]);
    cnt=0;
    for(i=n;i>=1;i--)
    {
        cnt++;
        x=a[i];
        for(j=head[x];j!=-1;j=Next[j])
        {
            y=to[j];
            if(p[y]==1)
            {
                fx=get(x);
                fy=get(y);
                if(fx!=fy)
                {
                    cnt--;
                    f[fx]=fy;
                }
            }
        }
        ans[i]=cnt;
        p[x]=1;
    }
    for(i=1;i<=n;i++)
        if(ans[i]==1) printf("YES\n");else printf("NO\n");
    return 0;
}

 

转载于:https://www.cnblogs.com/lwq12138/p/5514362.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值