题意:有n个竞选人,由m个人投票,每个人对竞选人都有一个排名,每次两个人竞选,m个人分别投票,每次两个人,胜利者继续参与竞选,失败者淘汰,剩余一个人的时候停止你希望让c最后获得胜利
,你可以安排每次参与竞选的两个竞选人,问是否有可能让c竞选成功
分析:胜利者向失败者连一条有向边,那么问题就转化为从c出发,是否能顺边访问所有的点,一次dfs遍历就行了
简图的时候,不是按照输入记录,记录竞选人在投票人心目中的排名,这样最后便于建图
#include<iostream> #include<Cstdio> #include<cstring> #include<algorithm> #include<vector> using namespace std; const int maxn=105; int d[maxn][maxn],n,m,c,x,vis[maxn]; vector<int> G[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]) dfs(v); } } int main(){ while(~scanf("%d%d%d",&n,&m,&c)&&n+m+c){ for(int i=1;i<=m;i++) for(int j=1;j<=n;j++){ scanf("%d",&x); d[i][x]=j; } for(int i=1;i<=n;i++)G[i].clear(); for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++){ int cnt=0; for(int k=1;k<=m;k++) if(d[k][i]<d[k][j]) cnt++; if(cnt>m/2) G[i].push_back(j); else G[j].push_back(i); } memset(vis,0,sizeof(vis)); dfs(c); int cnt=0; for(int i=1;i<=n;i++) if(vis[i]) cnt++; if(cnt==n) puts("yes"); else puts("no"); } return 0; }