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

本文介绍了一个农场关闭过程中的连通性判断问题。通过倒序并查集的方法,每次关闭一个谷仓,判断剩余谷仓是否仍保持全连通状态。初始状态及每次关闭后都需要输出是否全连通。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

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 barns connected with bidirectional paths between some pairs of barns (). 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.

FJ和他的奶牛们正在计划离开小镇做一次长的旅行,同时FJ想临时地关掉他的农场以节省一些金钱。

这个农场一共有被用M条双向道路连接的N个谷仓(1<=N,M<=3000)。为了关闭整个农场,FJ 计划每一次关闭掉一个谷仓。当一个谷仓被关闭了,所有的连接到这个谷仓的道路都会被关闭,而且再也不能够被使用。

FJ现在正感兴趣于知道在每一个时间(这里的“时间”指在每一次关闭谷仓之后的时间)时他的农场是否是“全连通的”——也就是说从任意的一个开着的谷仓开始,能够到达另外的一个谷仓。注意自从某一个时间之后,可能整个农场都开始不会是“全连通的”。
输入输出格式
输入格式:

The first line of input contains and . The next lines each describe a

path in terms of the pair of barns it connects (barns are conveniently numbered

). The final lines give a permutation of

describing the order in which the barns will be closed.

输出格式:

The output consists of lines, each containing “YES” or “NO”. The first line

indicates whether the initial farm is fully connected, and line indicates

whether the farm is fully connected after the th closing.

输入输出样例
输入样例#1:

4 3
1 2
2 3
3 4
3
4
1
2

输出样例#1:

YES
NO
YES
YES


倒序,并查集维护。


#include<iostream>
#include<vector>
#include<cstdio>
using namespace std;
vector<int>v[3005];
int n,m,cnt,f[3005],c[3005];
bool b[3005],bb[3005];
int fnd(int x)
{
    if(f[x]!=x)
        f[x]=fnd(f[x]);
    return f[x];
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        v[x].push_back(y);
        v[y].push_back(x);
    }
    for(int i=1;i<=n;i++)
        f[i]=i;
    for(int i=1;i<=n;i++)
        scanf("%d",&c[i]);
    for(int i=n;i>=1;i--)
    {
        bb[c[i]]=1;
        cnt++;
        for(int j=0;j<v[c[i]].size();j++)
            if(bb[v[c[i]][j]])
                if(fnd(v[c[i]][j])!=fnd(c[i]))
                {
                    f[fnd(v[c[i]][j])]=fnd(c[i]);
                    cnt--;
                }
        if(cnt==1)
            b[i]=1;
        else
            b[i]=0;
    }
    for(int i=1;i<=n;i++)
    {
        if(b[i])
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值