UVALive-7385-FlippingCards(并查集判环)
来源:互联网 发布:netstat -ano linux 编辑:程序博客网 时间:2024/06/06 01:57
题目链接:点击打开链接
题目大意:
现在有一些卡片,卡片的每一面有一个数字,判断是否能否把所有的卡片摆在桌子上,满足:任意一个任意一个数字出现次数不超过一次(任何数字不能两次朝上)。
解题思路:
一:把每个数字看成一个点,卡片上的数字间连接一条边,那么当某些数字能连成一个环时,这些数字必须每个都要出现一次(仔细想想),既然这样,那么这个环上面的数字就不能再参与其余环的形成,也不能与其余环相连(再仔细想想),那么我们把所有边建好后,就是判断图中是否有相连的环,有的话就impossible。
二:开始想到并查集,但是没想到可以用来判断环的个数: 只需要开一个数组记录,每个父结点的参与成环的个数,合并的时候,把两个父节点的值相加就好了。
三:当然也可以DFS()遍历,不过相比并查集就慢多了。
代码:
#include<iostream>#include<cstring>#include<string>#include<cstdio>#include<algorithm>using namespace std;const int maxn=5e4+10;int p[maxn<<1],cnt[maxn<<1];int FIND(int x){return p[x]==x?x:p[x]=FIND(p[x]);}int main(){ int T,n,u,v,x,y; scanf("%d",&T); while(T--){ scanf("%d",&n); for(int i=0;i<=2*n;i++)p[i]=i; memset(cnt,0,sizeof cnt); for(int i=0;i<n;i++){ scanf("%d%d",&u,&v); x=FIND(u); y=FIND(v); if(x==y)cnt[x]++; else {p[x]=y;cnt[y]+=cnt[x];} } int is_ok=1; for(int i=0;i<=2*n;i++){ if(cnt[i]>1){is_ok=0;break;} } if(is_ok)printf("possible\n"); else printf("impossible\n"); } return 0;}
阅读全文
0 0
- UVALive-7385-FlippingCards(并查集判环)
- UVALive - 3644 并查集
- UVALive 6187 并查集
- uvalive 3644(并查集)
- uvalive 3027(并查集)
- X-Plosives +uvalive+并查集+水题
- Corporative Network +uvalive+并查集
- UVALive 6091 - Trees (并查集)
- 【UVALive】6168 Fat Ninjas 并查集
- UVALive 3644 X-Plosives 并查集
- UVALive 6091 Trees 并查集(水
- UVALive - 3644 X-Plosives 并查集
- UVALive 4627 -- Islands (并查集)
- UVALive - 3644 X-Plosives 并查集
- UVALive - 3027 Corporative Network 并查集
- UVALive 7066 Intersection 求圆环面积并
- UVALive 4487 异或 并查集
- UVALive 6091 并查集简单应用
- C# 中的委托和事件
- Android ListView常用属性解析
- bzoj 1647: [Usaco2007 Open]Fliptile 翻格子游戏(枚举)
- C#事件(event)解析
- [BZOJ1095][ZJOI2007]Hide捉迷藏-动态树分治
- UVALive-7385-FlippingCards(并查集判环)
- 实战Metasploit之安卓渗透舍友
- POJ 1523:SPF tarjan求割点
- redis集群搭建
- brcmf
- UVa11988 Broken Keyboard
- Retorfit源码分析
- vim: 学习资料——基础
- vim修改颜色配置