JZOJ 3875. 【NOIP2014八校联考第4场第2试10.20】星球联盟(alliance)
来源:互联网 发布:淘宝可以人肉搜索 编辑:程序博客网 时间:2024/05/04 10:53
Description
在遥远的S星系中一共有N个星球,编号为1…N。其中的一些星球决定组成联盟,以方便相互间的交流。
但是,组成联盟的首要条件就是交通条件。初始时,在这N个星球间有M条太空隧道。每条太空隧道连接两个星球,使得它们能够相互到达。若两个星球属于同一个联盟,则必须存在一条环形线路经过这两个星球,即两个星球间存在两条没有公共隧道的路径。
为了壮大联盟的队伍,这些星球将建设P条新的太空隧道。这P条新隧道将按顺序依次建成。一条新轨道建成后,可能会使一些星球属于同一个联盟。你的任务是计算出,在一条新隧道建设完毕后,判断这条新轨道连接的两个星球是否属于同一个联盟,如果属于同一个联盟就计算出这个联盟中有多少个星球。
Input
第1行三个整数N,M和P,分别表示总星球数,初始时太空隧道的数目和即将建设的轨道数目。
第2至第M+1行,每行两个整数,表示初始时的每条太空隧道连接的两个星球编号。
第M+2行至第M+P+1行,每行两个整数,表示新建的太空隧道连接的两个星球编号。这些太空隧道按照输入的顺序依次建成。
Output
输出共P行。如果这条新的太空隧道连接的两个星球属于同一个联盟,就输出一个整数,表示这两个星球所在联盟的星球数。如果这条新的太空隧道连接的两个星球不属于同一个联盟,就输出”No”(不含引号)。
Sample Input
输入1:
3 2 1
1 2
1 3
2 3
输入2:
5 3 4
1 2
4 3
4 5
2 3
1 3
4 5
2 4
Sample Output
输出1:
3
输出2:
No
3
2
5
Data Constraint
对于 10% 的数据有
对于 40% 的数据有
对于 100% 的数据有
Hint
Solution
这一题是运用并查集的典例,使用灵活。
首先对所有边逐一处理,如果连了边之后不会形成环,就直接连边,否则打一个标记(不连)
其中可以用并查集维护两个端点是否属于同一个集合
以后处理出森林的每个点的父亲节点和深度
然后就开始处理未连的边,对于两个端点,
像找最近公共祖先一样,逐个逐个往上走,途中维护累加环的大小即可
总时间复杂度
O(M+P)
Code
#include<cstdio>using namespace std;const int N=500001;struct data{ int x,y;}edge[N];int tot,num,f1,f2;int f[N],g[N];int fa[N],dep[N];int first[N],next[N*4],en[N*4];bool bz[N];inline int read(){ int data=0; char ch=0; while(ch<'0' || ch>'9') ch=getchar(); while(ch>='0' && ch<='9') data=data*10+ch-'0',ch=getchar(); return data;}inline int get(int x){ return (f[x]==x)?x:f[x]=get(f[x]);}inline void insert(int x,int y){ next[++tot]=first[x]; first[x]=tot; en[tot]=y;}inline void dfs(int x,int y){ dep[x]=dep[fa[x]=y]+1; for(int i=first[x];i;i=next[i]) if(en[i]!=y) dfs(en[i],x);}inline void work(int v){ f1=edge[v].x,f2=edge[v].y; while(true) { f1=get(f1),f2=get(f2); if(f1==f2) return; if(dep[f1]>dep[f2]) { g[f[f1]=f2]+=g[f1]; g[f1]=0; f1=fa[f1]; }else { g[f[f2]=f1]+=g[f2]; g[f2]=0; f2=fa[f2]; } }}int main(){ int n=read(),m=read(),p=read(); for(int i=1;i<=n;i++) f[i]=i; for(int i=1;i<=m+p;i++) { f1=get(edge[i].x=read()); f2=get(edge[i].y=read()); if(f1!=f2) { f[f1]=f2; insert(edge[i].x,edge[i].y); insert(edge[i].y,edge[i].x); bz[i]=true; } } for(int i=1;i<=n;i++) if(!dep[i]) dfs(i,0); for(int i=1;i<=n;i++) g[f[i]=i]=1; for(int i=1;i<=m;i++) if(!bz[i]) work(i); for(int i=m+1;i<=m+p;i++) if(!bz[i]) { work(i); printf("%d\n",g[f1]); }else printf("No\n"); return 0;}
- JZOJ 3875. 【NOIP2014八校联考第4场第2试10.20】星球联盟(alliance)
- 【JZOJ3875】【NOIP2014八校联考第4场第2试10.20】星球联盟(alliance)
- 【NOIP2014八校联考第4场第2试10.20】星球联盟(alliance)
- 【JZOJ3875】【NOIP2014八校联考第4场第2试10.20】星球联盟(alliance)
- [jzoj]3875. 【NOIP2014八校联考第4场第2试10.20】星球联盟(alliance)(图论题,构树+缩点+LCA+并查集)
- 2017.08.20【NOIP提高组】模拟赛B组 【NOIP2014八校联考第4场第2试10.20】星球联盟(alliance)
- jzoj. 3873. 【NOIP2014八校联考第4场第2试10.20】乐曲创作(music)
- JZOJ 3852. 【NOIP2014八校联考第2场第2试9.28】单词接龙(words)
- JZOJ 3853. 【NOIP2014八校联考第2场第2试9.28】帮助Bsny(help)
- JZOJ 3870. 【NOIP2014八校联考第4场第1试10.19】单词检索(search)
- [JZOJ]3858. 【NOIP2014八校联考第3场第2试10.5】挖掘机技术哪家强
- [JZOJ]3859. 【NOIP2014八校联考第3场第2试10.5】孤独一生
- 【JZOJ3873】【NOIP2014八校联考第4场第2试10.20】乐曲创作(music)
- 【JZOJ3874】【NOIP2014八校联考第4场第2试10.20】准备复赛(exam)
- 【NOIP2014八校联考第4场第2试10.20】乐曲创作
- 【NOIP2014八校联考第4场第2试10.20】准备复赛
- 【JZOJ3873】【NOIP2014八校联考第4场第2试10.20】乐曲创作(music)
- 高中OJ3874. 【NOIP2014八校联考第4场第2试10.20】准备复赛(exam)
- 文件上传漏洞常见利用方式
- 如何开发微信小程序(一)个人开发者该如何测试开发小程序
- Java第三天,面向对象1
- Java文件操作---读写文件
- vs编译gtest
- JZOJ 3875. 【NOIP2014八校联考第4场第2试10.20】星球联盟(alliance)
- 【hibernate】session中的load和get对比
- GitLab的安装实战
- Volley—轻量级HTTP客户端网络请求框架
- stl算法设计理念_函数对象和函数对象当参数和返回值
- [SPOJ INS14G Kill them All]数学、排列组合
- 修改xml文件中节点的值
- VS2012+OpenCV2.4.9+Qt5.3.1环境配置
- Mac 程序员的十种武器