F - True Liars POJ 1417(并查集)(DFS)
来源:互联网 发布:政务软件 编辑:程序博客网 时间:2024/06/05 22:34
我的天!!做这道题发现两个重要的坑点!
1、 memset只能用于初始化数组的0和-1或者是16进制的比如0x3f3f3f3f;
2、字符数组越界了会影响后面变量的值!
好吧,搞了半天先是wa了好几发,最后超时了,过程中修复好多bug,能写出还是。。费了不少功夫,太弱了!
心累,mdzz!
查了发现是要用并查集加dp做,我的天!也可能是我的DFS优化不够,先存个代码过会再看吧。
#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>using namespace std;const int maxn = 1e4+5;int father[maxn],Rank[maxn],sum[maxn][3],vis[maxn][2],cnt,vv[maxn][2],summ[maxn][2];int query(int x) { //路径压缩 if(father[x] != x) { int per = father[x]; father[x] = query(father[x]); Rank[x] = (Rank[x] + Rank[per] + 2) %2; } return father[x];}void dfs(int sum1,int sum2,int i,int x,int y,int cc) { //dfs查有几种可行方案,如果只有唯一解,那么就是可行的,否则输出no //printf("%d-%d-%d-%d-%d-%d\n",sum1,sum2,i,x,y,cc); if(sum1 > x || sum2 > y) return ; if(sum1 == x && sum2 == y) { //printf("tt\n"); cnt++; if(cnt == 1){ for(int i = 1;i <= cc;i++) vv[i][0] = vis[i][0]; } return ; } if(cnt > 1 || i > (cc)) return ; int t = sum1 + sum[i][0]; int tt = sum2 + sum[i][1]; if(!vis[i][0]) { vis[i][0] = 1; i++; //printf("%d-%d-%d-%d-%d\n",t,tt,i,x,y,cc); dfs(t,tt,i,x,y,cc); i--; vis[i][0] = 0; // 每次检查先标记,回溯的时候再消除标记。 } int j = sum1 + sum[i][1]; int jj = sum2 + sum[i][0]; if(!vis[i][1]) { //printf("%d=%d=%d=%d=%d\n",j,jj,i,x,y,cc); vis[i][1] = 1; i++; dfs(j,jj,i,x,y,cc); i--; vis[i][1] = 0; }}int main() { //freopen("haha.txt","r",stdin); int m,nx,ny; while(~scanf("%d%d%d",&m,&nx,&ny) && (m || ny || nx)) { int x,y; if(nx == ny) { char str[20]; for(int i = 1;i <= m;i++) scanf("%d%d%s",&x,&y,str); printf("no\n"); continue; } int n = (nx + ny); char str[20]; //开字符数组的时候要记得开大一些 for(int i = 0;i <= n;i++) { Rank[i] = 0; father[i] = i; } for(int i = 1;i <= m;i++) { scanf("%d%d%s",&x,&y,str); int a = query(x); int b = query(y); if(a != b) { father[b] = a; if(str[0] == 'y') Rank[b] = (Rank[x] - Rank[y] + 2) % 2; else if(str[0] == 'n') Rank[b] = (Rank[x] - Rank[y] + 3) % 2; } } memset(summ,0,sizeof(summ)); //memset只能用于16进制和0或者-1 memset(sum,0,sizeof(sum)); memset(vis,0,sizeof(vis)); for(int i = 1;i <= n;i++) { int zz = query(i); if(!Rank[i]) summ[zz][0]++; else summ[zz][1]++; } int cc = 0; for(int i = 1;i <= n;i++) { if(summ[i][0] || summ[i][1]) { sum[++cc][0] = summ[i][0]; sum[cc][1] = summ[i][1]; sum[cc][2] = i; } } cnt = 0; dfs(0,0,1,nx,ny,cc); //printf("%d=",cnt); if(cnt == 1) { int nn[2005],sss = 0; for(int i = 1;i <= cc;i++) { //按顺序输出善良的人的编号 if(vv[i][0]) { for(int j = 1;j <= n;j++) { if(query(j) == sum[i][2] && !Rank[j]) nn[sss++] = j; } } else { for(int j = 1;j <= n;j++) { if(query(j) == sum[i][2] && Rank[j]) nn[sss++] = j; } } } sort(nn,nn+sss); for(int i = 0;i < sss;i++) printf("%d\n",nn[i]); printf("end\b"); } else printf("no\n"); /*for(int i = 1;i <= cc;i++) printf("%d-%d ",sum[i][0],sum[i][1]); printf("\n");*/ } return 0;}
0 0
- F - True Liars POJ 1417(并查集)(DFS)
- poj 1417 True Liars (并查集+dp)
- POJ 1417 True Liars(并查集+DP)
- POJ-1417-并查集-True Liars
- POJ--1417[True Liars] 并查集+背包
- poj 1417 True Liars 解题报告 并查集 DP
- POJ 1417 True Liars(并查集+DP)
- poj 1417 - True Liars(并查集+背包)
- POJ 1417 True Liars(并查集+DP)
- poj-1417 True Liars 并查集+DP
- poj 1417 True Liars(并查集+DP)
- poj -- 1417 True Liars(并查集 + dp)
- POJ 1417 True Liars 带权并查集+DP
- True Liars (并查集+dp,待续、、)
- poj1417 true liars(并查集 + DP)详解
- POJ1417 True Liars (并查集+背包)
- POJ 1417 True Liars(路径压缩并查集+DP背包问题)
- poj 1417 True Liars 带权并查集+母函数dp
- rem计算更简洁方法(不支持缩放)
- 重要函数
- 生成验证码的java类(未测试)
- ccnu_2016_暑期模拟赛(2)---bfs
- potplay皮肤装扮
- F - True Liars POJ 1417(并查集)(DFS)
- MFC中热键&模拟键盘&模拟鼠标的使用
- HDOJ 1009之FatMouse' Trade
- Poj1190 生日蛋糕 DFS
- JAVA 发送下载文件(未测试)
- Testing OpenStack NUMA (by quqi99)
- 使用双重指针实现链表结点的插入与删除
- Rsync同步不需要密码的绝对可行版本!
- android 6.0系统扫不到Ble蓝牙问题