BNUOJ 1037 精神控制
XsuagrX喜欢到处唬人,各种唬。这不,经过刻苦修炼,他终于掌握了Bane Element的Ultra绝技加强版,恶魔掌控(快捷键F)(YY中&……)。当XsugarX对某个人胡言乱语Q@# @时,可以控制这个人的行动,并且被完全控制的人会对其他人继续胡言乱语,但是他们只能控制被胡言乱语的人的部分精神,当满足如下条件时,我们说A控制B:
1、 A控制了B大于等于50%的精神。
2、 A控制了Ci,Ci控制了Bi Di%的精神,而∑Di≧50
有一天他心血来潮对着N个人一通@#Q%#$#后,想知道究竟那些人被其他人控制了。
现在你的任务是读入n组i控制j精神的p%,并输出数对(p,q)表示p控制q。
由于能力有限,XsugarX最多只能控制100个人,且所有人的编号均小于100。
Input
第一行一个数Z表示有Z组测试数据
对于每组测试数据
第一行一个n,表示有n个控制关系。
以下n行,每行一组(i,j,k)表示编号i的人控制编号j的人精神的k%
Output
对于每组数据,输出所有的控制关系,按升序排列,每组答案最后输出一个空行。
Sample Input
1 3 1 2 80 2 3 80 3 1 20
Sample Output
1 2 1 3 2 3
233333有一阵子没写博客了来一发,开学忙着复习苦逼的补考,高数大法坑死人。
这道题零零碎碎搞了一星期,最后才发现题意理解还有问题,这是一个要列加的图,比如两条路单走那个都不通合起来看就通了2333绝对坑。
原来搞错掉的代码也贴过来了关键是第一次摆出容器大干一场。set的反向排序还没搞出来再看看,图搜索的基本想法get。这道题复杂两个二维数组就能搞定,后面是正确代码。
WA掉的代码
#include<iostream> #include<cstdio> #include<vector> #include<stack> #include<set> #include<algorithm> using namespace std; struct donser { vector <int> son; vector <int> num; }; donser d[110]; stack <int> dong; set <int> dongser; int i,j,k; int a,b,c,e,p,q,t; void loop(int m) { for(vector<int>::iterator iter=d[m].son.begin();iter!=d[m].son.end();iter++) { t=dongser.size(); if(*iter==m){continue;} dongser.insert(*iter); q=dongser.size(); if(q==t){continue;} loop(*iter); } } int main() { freopen("stdin.txt","r",stdin); while(~scanf("%d",&j)) { scanf("%d",&k); for(i=1;i<=k;i++) { scanf("%d %d %d",&a,&b,&c); if(c>=50){d[a].son.push_back(b);d[a].num.push_back(c);} } for(i=1;i<=100;i++) { if(d[i].son.size()==0){continue;} loop(i); set<int>::reverse_iterator j; for(j=dongser.rbegin();j!=dongser.rend();j++) { dong.push(*j); } while(dong.size()>0) { printf("%d %d\n",i,dong.top()); dong.pop(); } dongser.clear(); } } return 0; }
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; int n,t,x,y,num,donser[110][110]; bool rank,a[110][110],dong[110]; int main() { freopen("stdin.txt","r",stdin); scanf("%d",&t); while(t--){ scanf("%d",&n); memset(a,0,sizeof(a)); memset(donser,0,sizeof(donser)); memset(dong,0,sizeof(dong)); while(n--){ scanf("%d%d%d",&x,&y,&num); donser[x][y] += num; dong[x] = dong[y] = 1; if(donser[x][y] >= 50) a[x][y] = 1; } n = 100; for(int i = 1;i <= n;++i) a[i][i] = 1; while(1){ rank = 1; for(int i = 1;i <= n;++i) for(int j = 1;j <= n;++j){ if(a[i][j]) continue; num = 0; for(int k = 1;k <= n;++k) if(a[i][k]) num += donser[k][j]; if(num >= 50) { a[i][j] = 1; rank = 0; } } if(rank) break; } for(int i = 1;i <= n;++i) if(dong[i]) for(int j = 1;j <= n;++j) if(dong[j] && i != j && a[i][j]) printf("%d %d\n",i,j); puts(""); } return 0; }