uva 11748
题意:有N个人竞选,有M个投票人,每个投票人对竞选者都有个排序.投票人对于两个竞选者,他会投排在前面的竞选者的票.
每次有2个竞选人出来竞选,失败者退出,获胜者则回到竞选候选人里,直到最后一人.
现在你想要某人S获胜,并且你能随意安排两个人出来竞选.
分析:构图,每两个人A,B,若A获的票数大于B,则连A->B的边,否则连B->A的边.最后求S是否能遍历整个图,若能遍历则输出"yes",否则输出"no";
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<algorithm> #include<queue> #include<string> #include<vector> #include<map> using namespace std; vector<int> e[105]; int n,m,pos,mp[105][105]; bool vis[105]; void dfs(int u) { vis[u]=1; for(int i=0;i<e[u].size();i++) { int v=e[u][i]; if(vis[v]) continue; dfs(v); } } int main() { while(scanf("%d%d%d",&n,&m,&pos)!=EOF) { if(n+m+pos==0) break; int x,cnt=0; memset(mp,0,sizeof(mp)); memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++) e[i].clear(); for(int i=1;i<=m;i++) { for(int j=1;j<=n;j++) { scanf("%d",&x); mp[i][x]=j; } } for(int i=1;i<=n;i++) { for(int j=i+1;j<=n;j++) { cnt=0; for(int k=1;k<=m;k++) { if(mp[k][i]<mp[k][j]) cnt++; } if(cnt>m/2) e[i].push_back(j); else e[j].push_back(i); } } dfs(pos); cnt=0; for(int i=1;i<=n;i++) { if(vis[i]) cnt++; } if(cnt==n) printf("yes\n"); else printf("no\n"); } return 0; }