Dominos<并查集求解>
来源:互联网 发布:素颜美女知乎 编辑:程序博客网 时间:2024/06/05 00:22
1900: Problem D: Dominos
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 97 Solved: 18
[Submit][Status][Web Board]
Description
Problem D: Dominos
Dominos are lots of fun. Children like to stand the tiles on their side in long lines. When one domino falls, it knocks down the next one, which knocks down the one after that, all the way down the line. However, sometimes a domino fails to knock the next one down. In that case, we have to knock it down by hand to get the dominos falling again.
Your task is to determine, given the layout of some domino tiles, the minimum number of dominos that must be knocked down by hand in order for all of the dominos to fall.
Input
The first line of input contains one integer specifying the number of test cases to follow. Each test case begins with a line containing two integers, each no larger than 100 000. The first integer n is the number of domino tiles and the second integer m is the number of lines to follow in the test case. The domino tiles are numbered from 1 to n. Each of the following lines contains two integers x and y indicating that if domino number x falls, it will cause domino number y to fall as well.
Output
For each test case, output a line containing one integer, the minimum number of dominos that must be knocked over by hand in order for all the dominos to fall.
Sample Input
Sample Output
HINT
Source
真的是错了几百遍才AC的题目,因为各种状况没有考虑到,最先看到这个题,立马就动手写了并查集,结果一提交就WA ,后来跟大佬们聊了会才发现,并查集他是一种双向存储,而题目中的意思只能是单向.
eg :
1
3 2
1 2
3 2
这种数据用并查集做出来的是1 但是实际上答案应该为2,考虑到这种情况,思路转了一下,又想起了当时AC 冠军代码的那道题,直接用一个数组把被推倒的骨牌存起来,然后没有被推倒过的骨牌就只能用手推啦 ,想到这我以为这就是个超级水超级水的水题了,然后一改代码提交,又是WA,好吧,再仔细找案例,就发现第二种做法有一种特殊情况:
eg :
1
3 3
1 2
2 1
1 3
这种如果用我刚刚说的方法来解,答案为0,而实际上应该为2,骨牌1和骨牌2成环,需要推一次(现实中两个牌应该不能成环的,这里不过举个例子),骨牌3单独一个需要推一次。
所以啊综上,我就直接把两种情况都一起考虑进来,直接输出两者的最大值,这样就把可能出错的情况都考虑进来了,然而又掉进了一个坑导致WA 。。。。
在设置数组来存储被推倒的骨牌是时,下标要跟骨牌的标号一致,(可能说的不太明白,直接上代码吧!)
#include<cstdio>#include<cstring>#include<cctype>#include<algorithm>#include<set>#include<cstring>#include<string>#include<iostream>#include<cmath>#include<map>using namespace std;int n;int pa[100005];int rank[100005];int find(int x){ if(x != pa[x]) pa[x] = find(pa[x]); return pa[x];}void unions(int x, int y){ x = find(x); y = find(y); if(x == y)return ;//如果父亲一致,就不用合并 n--;//如果不一致,把总数减一,和我们之前做的宗教问题一样。 if(rank[x] > rank[y]) { pa[y] = x; } else { pa[x] = y; if(rank[x] == rank[y]) rank[y]++; }}int v[100005];int main(){ int t; scanf("%d",&t); while(t--){ memset(v,0,sizeof(v)); int m; scanf("%d %d",&n,&m); int tt=n; for(int i=0;i<=n;i++)//这个地方的初始化导致了多次WA,根据我自己的代码,v[i]表示的第i个骨牌被推倒,但是之前我的循环到n-1就结束了,导致了第n个没有被初始化 { pa[i]=i; rank[i]=0; } int a,b; for(int i=0;i<m;i++){ scanf("%d %d",&a,&b); unions(a,b); v[b]=1; } int sum=0; for(int i=1;i<=tt;i++) if(!v[i]){ sum++; // printf("i:%d\n",i); } printf("%d\n",max(sum,n)); } return 0;}
- Dominos<并查集求解>
- 并查集求解问题
- POJ1611 The Suspects 并查集求解
- 并查集--求解等价问题
- Virtual Friends<并查集+map求解>
- 用并查集求解连通分量问题
- POJ 1611:The Suspects 并查集求解
- Kruscal算法+并查集 求解最小生成树
- Kruscal算法 并查集求解最小生成树
- 并查集 求解最小生成树 Kruscal算法
- nefu 676 并查集求解树的深度
- POJ 1797Heavy Transportation Kruskal并查集求解
- POJ 1308Is It A Tree? 并查集求解
- hdu-1233最小生成树并查集求解
- 编程之美--区间重合判断(并查集求解)
- HDOJ 1232:畅通工程 并查集求解子图的个数
- 杭电hdu 3038 how many answers are wrong 并查集求解
- hdu3472-并查集+混和图的欧拉回路(网络流求解)
- OnClickListener多点击处理
- 20170713
- android 7.1 服务进程 open串口设备失败
- 关于MyEclipse下的项目无法使用BASE64Encoder问题的解决办法
- 解决Java调用https服务证书错误javax.net.ssl.SSLHandshakeException
- Dominos<并查集求解>
- boot中的命令行解析器
- c++设计模式之单例模式
- vue-router总结
- Q123:PBRT-V3,各种形式的“光传播方程”的推导依据
- Java常识 ------分支语句(for do---while while语句)
- ConstraintLayout属性详解和Chain的使用
- JvavScript与java中的正则表达式的区别
- JS设置cookie、读取cookie、删除cookie