题目描述

in English:
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 NN barns connected with MM bidirectional paths between some pairs of barns (1 \leq N, M \leq 30001≤N,M≤3000 ). 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.

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

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

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

说白了就是:

有N个农场,编号为1到N,有M条双向公路连接,其中1≤N,M≤200000,每次封锁一个农场,
当一个农场被封闭时,和该农场连接的道路全部断开,不能再通行。现在给出一个封锁顺序,
请计算每次封锁一个农场后,剩余的未封锁的农场是否连通。

输入输出格式

in English:

输入格式:
The first line of input contains NN and MM . The next MM lines each describe a

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

1 \ldots N1…N ). The final NN lines give a permutation of 1 \ldots N1…N

describing the order in which the barns will be closed.

输出格式:
The output consists of NN lines, each containing “YES” or “NO”. The first line

indicates whether the initial farm is fully connected, and line i+1i+1 indicates

whether the farm is fully connected after the ii th closing.

in Chinese:

Input Data
第一行,包含两个整数N和M。
接下来M行,每行两个整数,描述一条道路。
接下来N行,每行一个整数,依次表示封锁的农场编号。

Output Data
输出包含N行,每行一个字符串“YES”或者“NO”,表示连通或者不连通。
其中第i行,表示第i个农场未被封锁时,所有未被封锁的农场的连通情况。
第i+1行,表示第i个农场被封锁后,所有未被封锁的农场的连通情况。
特别地,第1行表示所有农场未被封锁前,所有农场的连通情况。

输入输出样例

输入样例#1:
4 3
1 2
2 3
3 4
3
4
1
2
输出样例#1:
YES
NO
YES

然后我看着这道题就码出了第一个程序:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<vector> using namespace std;
int n,m,f[210000];
bool close[210000],t[210000];
vector <int> pat[210000]; int fa(int x)
{
if(f[x]==x) return x;
return f[x]=fa(f[x]);
} bool check()
{
bool one=false;
for(int i=1;i<=n;++i)
f[i]=i;
for(int i=1;i<=n;++i) if(!close[i])
for(int j=0;j<pat[i].size();++j)
{
if(close[pat[i][j]]) continue;
int fx=fa(i),fy=fa(pat[i][j]);
if(fx!=fy) f[fx]=fy;
}
/*然后这里判断连通图的个数的方法也很朴素, 就是查祖先的个数是否超过了1,就酱*/
for(int i=1;i<=n;++i)
if(!close[i] && f[i]==i)
{
if(!one) one=true;
else return false;
}
return true; //通过了检测之后直接返回TRUE(表示联通)
} int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;++i) //就是记录了一下每个点的联通边
{
int from,to;
scanf("%d%d",&from,&to);
pat[from].push_back(to);
pat[to].push_back(from);
} if(check()) printf("YES\n"); //先是没删点的时候跑一遍check
else printf("NO\n"); for(int i=1;i<n;++i)//然后这里就是按顺序来,读一个点,删一个点,再看图是否联通
{
int x; scanf("%d",&x);
close[x]=1;
if(check()) printf("YES\n");
else printf("NO\n");
}
return 0;
}

然后我惊奇的发现洛谷上A了,这数据是真心水,这样也能水过去(吸口氧貌似还能再降三分之二的时间)。

然后看到这里哭了T_T

换个地儿评测TLE!还能不能愉快的玩耍了?

行,这数据真心强!我还真不信就倒在这儿了_ (:зゝ∠) _
于是乎我就换了个方法:做个倒过来的并查集。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<vector> using namespace std;
int n,m,f[210000],add[210000];
bool open[210000],t[210000];
vector <int> pat[210000]; int read(){
int x=0; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) x=x*10+c-'0',c=getchar();
return x;
} int fa(int x)
{
if(f[x]==x) return x;
return f[x]=fa(f[x]);
} bool check(int x)
{
bool one=false;
for(int i=0;i<pat[x].size();++i)
//没什么两样,就是把能和新开张的农场相连的农场合并了一下
{
if(!open[pat[x][i]]) continue;
int fx=fa(x),fy=fa(pat[x][i]);
if(fx!=fy) f[fx]=fy;
}
for(int i=1;i<=n;++i)
//判断还是老办法(TLE最根本的原因也是在这里,这个等会儿讲)
if(open[i] && f[i]==i)
{
if(!one) one=true;
else return false;
}
return true;
} int main()
{
n=read();m=read();
for(int i=1;i<=m;++i)
{
int from=read(),to=read();
pat[from].push_back(to);
pat[to].push_back(from);
}
for(int i=1;i<=n;++i) //并查集的预处理就直接放在主函数里了
f[i]=i; for(int i=1;i<=n;++i) //然后实现倒着把数据读入
add[n-i]=read();
open[add[0]]=1; //表示第一家农场开门
t[n]=1;
for(int i=1;i<n;++i)
{
open[add[i]]=1; //然后一家接着一家开门(抢生意)
if(check(add[i])) t[n-i]=1; //如果check出来图联通了,就(反着)标记t为1
}
for(int i=1;i<=n;++i) //然后按读入的顺序输出
if(t[i]) printf("YES\n");
else printf("NO\n"); return 0;
}

然后洛谷上一交,心里美滋滋:

时间降了十倍左右!这下还会爆就真是。。。额

兵败如山倒= =

_ ( :зゝ∠)_这次是真爬不起来了QAQ

然而我最后还是爬起来了_ ( :зゝ∠)_ (其实也就是做了个判断优化 = =|||)

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<vector> using namespace std;
int n,m,ans,f[210000],add[210000];
bool open[210000],t[210000];
vector <int> pat[210000]; int read(){
int x=0; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) x=x*10+c-'0',c=getchar();
return x;
} int fa(int x)
{
if(f[x]==x) return x;
return f[x]=fa(f[x]);
} bool check(int x)
{
++ans; //其他我都不想介绍了,主要也就是这里。。。
//ans++代表多了一个图(新开张的农场自为一个图)
for(int i=0;i<pat[x].size();++i)
{
if(!open[pat[x][i]]) continue;
int fx=fa(x),fy=fa(pat[x][i]);
if(fx!=fy) f[fx]=fy,ans--;
//然后在这里进行一个减图操作,如果两个集合合并了,图必然--,然后ans就--了
} if(ans) //最后判断一下多余的图是否为0,是的话就返回FALSE就这么easy(卡了我60)
return false;
return true;
} int main()
{
n=read();m=read();
for(int i=1;i<=m;++i)
{
int from=read(),to=read();
pat[from].push_back(to);
pat[to].push_back(from);
}
for(int i=1;i<=n;++i)
f[i]=i; for(int i=1;i<=n;++i)
add[n-i]=read();
open[add[0]]=1;
for(int i=1;i<n;++i)
{
open[add[i]]=1;
if(check(add[i])) t[n-i]=1;
}
for(int i=1;i<n;++i)
if(t[i]) printf("YES\n");
else printf("NO\n");
printf("YES\n"); return 0;
}

然后洛谷上又A了一遍,时间又降了一半的样子(虽说A了还是没有什么喜悦的赶脚,毕竟连跪了两把T_T)

然后又去挑战了一下BOSS:

终于A了!_ (||Xゝ∠)_

然后我就这样跪着(不如说是躺着)过了一道(巨)坑。。。 _ (:зゝ∠)_

然后本blog就结束了,童鞋们下次见!

一道并查集的(坑)题:关闭农场closing the farm的更多相关文章

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

    农夫约翰和他的奶牛准备去旅行,所以约翰想要把他的农场临时关闭. 农场有N个牛棚(牛棚从1到N编号),有M条路连接这些牛棚(1≤N,M≤3000). 约翰打算挨个关闭牛棚,在关牛棚的时候, 他突然想起一 ...

  2. [USACO16OPEN]关闭农场Closing the Farm(洛谷 3144)

    题目描述 Farmer John and his cows are planning to leave town for a long vacation, and so FJ wants to tem ...

  3. poj 2236:Wireless Network(并查集,提高题)

    Wireless Network Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 16065   Accepted: 677 ...

  4. poj 2524:Ubiquitous Religions(并查集,入门题)

    Ubiquitous Religions Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 23997   Accepted:  ...

  5. poj 1611:The Suspects(并查集,经典题)

    The Suspects Time Limit: 1000MS   Memory Limit: 20000K Total Submissions: 21472   Accepted: 10393 De ...

  6. hrbustoj 1073:病毒(并查集,入门题)

    病毒Time Limit: 1000 MS Memory Limit: 65536 KTotal Submit: 719(185 users) Total Accepted: 247(163 user ...

  7. POJ1182食物链(并查集经典好题)

    题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=66964#problem/E 题目思路:主要有两种思路:1.带权并查集2.挑战程 ...

  8. 并查集基础 模板题 hdu1232 畅通工程

    模板题 引入并查集——一则有趣的故事 为了解释并查集的原理,我将举一个更有趣的例子.话说江湖上散落着各式各样的大侠,有上千个之多.他们没有什么正当职业,整天背着剑在外面走来走去,碰到和自己不是一路人的 ...

  9. 洛谷 P3367 并查集 【模板题】

    题目描述 如题,现在有一个并查集,你需要完成合并和查询操作. 输入输出格式 输入格式: 第一行包含两个整数N.M,表示共有N个元素和M个操作. 接下来M行,每行包含三个整数Zi.Xi.Yi 当Zi=1 ...

随机推荐

  1. shiro默认登录

    业务需要,A项目跳转到B项目进行相关操作.而B项目使用的是shiro登录验证,懵逼了半天,好吧我很菜. 当然你也可以在shiro配置文件中放过这些方法,但是为了安全考虑需要遵守这些规则. 因此A跳转到 ...

  2. sqlyog创建数据库表关系图

    作为一个后台前端,数据库,需求分析,运维,PPT全包的码农来说.uml建模不存在的,对不起我没有时间,就用sqlyog拉几个你看看吧.看的懂的一眼就看清了,看不懂的整再好也是白瞎. 第一步:选择增强工 ...

  3. Maccms8.x 命令执行漏洞分析

    下载链接https://share.weiyun.com/23802397ed25681ad45c112bf34cc6db 首先打开Index.php $m = be('get','m'); m参数获 ...

  4. POJ - 2096 Collecting Bugs(概率dp)

    https://vjudge.net/problem/POJ-2096 题意 一个软件有s个子系统,会产生n种bug.某人一天发现一个bug,这个bug属于某种bug,发生在某个子系统中.求找到所有的 ...

  5. bzoj千题计划318:bzoj1396: 识别子串(后缀自动机 + 线段树)

    https://www.lydsy.com/JudgeOnline/problem.php?id=1396 后缀自动机的parent树上,如果不是叶子节点,那么至少有两个子节点 而一个状态所代表子串的 ...

  6. python 可视化库

    在做titanic分析的过程中,看了一些大神的想法,发现在分析数据的过程中,许多大神会使用到seaborn,plotly这些库,而我等小白仅仅知道matplotlib这个唯一的数据可视化库而已.上网查 ...

  7. zookeeper的安装与使用

    zookeeper的安装与使用: Zookeeper简介 1.可以作为集群的管理工具使用. 2.可以集中管理配置文件. Zookeeper是一个高效的分布式协调服务,可以提供配置信息管理.命名.分布式 ...

  8. HTTP 错误 500.21 - Internal Server Error 处理程序“WebServiceHandlerFactory-Integrated”在其模块列表中有一个错误模块“ManagedPipelineHandler”

    解决方案是 解决方案:只需要重新安装一下就可以了.在Frameworv4.0的目录中安装的程序以管理员权限重新运行一下就可以了. %windir%\Microsoft.NET\Framework\v4 ...

  9. extjs.net list 点击弹出修改页面及初始化

    <SaveMask ShowMask="true" /> <LoadMask ShowMask="true" /> <Listen ...

  10. article2pdf (Wordpress plug-in) Multiple vulnerabilities(CVE-2019-1000031, CVE-2019-1010257)

    Product: article2pdf (Wordpress plug-in)Product Website: https://wordpress.org/plugins/article2pdf/A ...