1 条题解
-
0
编号为 的 个人两两之间进行比赛,一共进行 场,只有胜负两种结果,不会出现平局。
有 场已经结束,第 场比赛中,人 战胜了人 。
请升序输出所有可能单独获得冠军的人,即该人的胜场数可能比其他任何人的胜场数都多。
。
我们假设第 个人已经赢了 场,输了 场。
我们考虑枚举获得冠军的人 ,那我们肯定让他赢 场,于是其他人不能赢超过 场。
于是我们建 个点表示每一场比赛,源点向比赛的点连容量为 的边, 场确定的比赛连向胜者的点。对于和 有关的未确定的比赛连向 ,其余的连向比赛的两个人的点(这些边的容量都为 )。
然后 向汇点连容量为 的边,其余人的点向汇点连容量为 的边。
最后看最大流是不是等于 即可。

#include<bits/stdc++.h> #define FL(i,a,b) for(int i=(a);i<=(b);i++) #define FR(i,a,b) for(int i=(a);i>=(b);i--) #define ll long long #define ull unsigned long long #define ld long double #define PII pair<int,int> using namespace std; const int MAXN = 50 + 10; const int MR = 3e3 + 10; const int MAXM = 2e4 + 10; const int inf = 0x3f3f3f3f; int n,m; int S,T,tot; PII c[MR]; int a[MAXN],b[MAXN]; int ID[MAXN][MAXN]; bool us[MAXN][MAXN]; int head[MR],now[MR],cnt=1; int dis[MR]; struct node{ int v,w,nxt; }e[MAXM]; void Add_edge(int u,int v,int w){ e[++cnt].v=v; e[cnt].w=w; e[cnt].nxt=head[u]; head[u]=cnt; } bool bfs(){ FL(i,S,T) dis[i]=inf; queue<int>q; now[S]=head[S],dis[S]=0,q.push(S); while(!q.empty()){ int u=q.front(); q.pop(); for(int i=head[u];i;i=e[i].nxt){ int v=e[i].v,w=e[i].w; if(w&&dis[v]==inf){ now[v]=head[v],dis[v]=dis[u]+1,q.push(v); if(v==T) return 1; } } } return 0; } int dfs(int u,int flow){ if(u==T) return flow; int res=0; for(int i=now[u];i;i=e[i].nxt){ int v=e[i].v; now[u]=i; if(e[i].w&&(dis[v]==dis[u]+1)){ int tmp=dfs(v,min(flow,e[i].w)); if(!tmp) dis[v]=inf; e[i].w-=tmp,e[i^1].w+=tmp; flow-=tmp,res+=tmp; } } return res; } int dinic(){ int res=0; while(bfs()) res+=dfs(S,inf); return res; } int main(){ scanf("%d%d",&n,&m),S=0,T=n+n*(n-1)/2+1,tot=n; FL(i,1,n) FL(j,i+1,n) ID[i][j]=ID[j][i]=++tot; FL(i,1,m){ scanf("%d%d",&c[i].first,&c[i].second); a[c[i].first]++,b[c[i].second]++; us[c[i].first][c[i].second]=us[c[i].second][c[i].first]=1; } FL(id,1,n){ int k=n-1-b[id]; cnt=1; FL(i,S,T) head[i]=0; FL(i,1,n) FL(j,i+1,n) Add_edge(S,ID[i][j],1),Add_edge(ID[i][j],S,0); FL(i,1,m) Add_edge(ID[c[i].first][c[i].second],c[i].first,1),Add_edge(c[i].first,ID[c[i].first][c[i].second],0); FL(i,1,n){ FL(j,i+1,n){ if(us[i][j]) continue; if(i==id||j==id) Add_edge(ID[i][j],id,1),Add_edge(id,ID[i][j],0); else Add_edge(ID[i][j],i,1),Add_edge(i,ID[i][j],0), Add_edge(ID[i][j],j,1),Add_edge(j,ID[i][j],0); } } FL(i,1,n) Add_edge(i,T,k-1+(id==i)),Add_edge(T,i,0); if(dinic()==n*(n-1)/2) printf("%d ",id); } }
- 1
信息
- ID
- 12404
- 时间
- 2000ms
- 内存
- 1024MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者