题意:有N个人竞选,有M个投票人,每个投票人对竞选者都有个排序.投票人对于两个竞选者,他会投排在前面的竞选者的票.
每次有2个竞选人出来竞选,失败者退出,获胜者则回到竞选候选人里,直到最后一人.
现在你想要某人S获胜,并且你能随意安排两个人出来竞选.
分析:构图,每两个人A,B,若A获的票数大于B,则连A->B的边,否则连B->A的边.最后求S是否能遍历整个图,若能遍历则输出"yes",否则输出"no";
// File Name: 11748.cpp // Author: Zlbing // Created Time: 2013/3/28 20:36:10 #include<iostream> #include<string> #include<algorithm> #include<cstdlib> #include<cstdio> #include<set> #include<map> #include<vector> #include<cstring> #include<stack> #include<cmath> #include<queue> using namespace std; #define CL(x,v); memset(x,v,sizeof(x)); #define INF 0x3f3f3f3f #define LL long long #define REP(i,r,n) for(int i=r;i<=n;i++) #define RREP(i,n,r) for(int i=n;i>=r;i--) const int MAXN=105; int n,m,c; int A[MAXN][MAXN]; vector<int> G[MAXN]; int vis[MAXN]; void dfs(int u) { vis[u]=1; for(int i=0;i<G[u].size();i++) { int v=G[u][i]; if(vis[v])continue; dfs(v); } } int main() { while(~scanf("%d%d%d",&n,&m,&c)) { if(n==0)break; int a; REP(i,1,m) { REP(j,1,n) { scanf("%d",&a); A[i][a]=j; } } REP(i,1,n)G[i].clear(); REP(i,1,n) REP(j,i+1,n) { int cnt=0; REP(k,1,m) { if(A[k][i]<A[k][j]) cnt++; } if(cnt>m/2) G[i].push_back(j); else G[j].push_back(i); } CL(vis,0); dfs(c); int cnt=0; REP(i,1,n) if(vis[i])cnt++; if(cnt==n)printf("yes\n"); else printf("no\n"); } return 0; }