SGU 326 网络流
2016-05-07 15:49
405 查看
题目大意:NBA 某小组内有 N 支球队,小组内以及小组间已经进行了若干场比赛。现在给
出这 N 支球队目前胜利的场数、还剩多少场没有比(包括小组内和小组间)以
及小组内任意两支球队之间还剩多少场没有比,问能否合理安排剩下的所有比赛,
使得球队 1 最后胜利的场数至少和小组内任何一支其他球队一样。
(2 <= N <= 20,
0 <= x <= 10000, x 表示其他任何输入)
同样,所有和球队 1 相关的比赛全让球队 1 赢,如果此
时仍有某支球队胜利的场数大于球队 1,则已经不可能满足要求。按如下方法建
图:所有小组内的比赛 i(不包括与球队 1 相关的比赛)作为一个点并加边(s, i,
num[i]),每支球队(不包括球队 1)作为一个点并加边(j, t, wins[1]-wins[i]),每场
比赛向与其关联的两支球队 u, v 连边(i, u, ∞), (i, v, ∞)。至于其他球队小组间的
比赛,直接让他们输掉就好,不用管。若最大流等于∑num[i]则可以满足要求。
ps:此类比赛的问题一般将比赛和球队作为点,源点向每个比赛的点连一条场数的边,每个比赛向参加比赛的球队连边(流量视情况而定),然后每个球队向汇点连一条边,流量即为该球队胜场的限制.
出这 N 支球队目前胜利的场数、还剩多少场没有比(包括小组内和小组间)以
及小组内任意两支球队之间还剩多少场没有比,问能否合理安排剩下的所有比赛,
使得球队 1 最后胜利的场数至少和小组内任何一支其他球队一样。
(2 <= N <= 20,
0 <= x <= 10000, x 表示其他任何输入)
同样,所有和球队 1 相关的比赛全让球队 1 赢,如果此
时仍有某支球队胜利的场数大于球队 1,则已经不可能满足要求。按如下方法建
图:所有小组内的比赛 i(不包括与球队 1 相关的比赛)作为一个点并加边(s, i,
num[i]),每支球队(不包括球队 1)作为一个点并加边(j, t, wins[1]-wins[i]),每场
比赛向与其关联的两支球队 u, v 连边(i, u, ∞), (i, v, ∞)。至于其他球队小组间的
比赛,直接让他们输掉就好,不用管。若最大流等于∑num[i]则可以满足要求。
ps:此类比赛的问题一般将比赛和球队作为点,源点向每个比赛的点连一条场数的边,每个比赛向参加比赛的球队连边(流量视情况而定),然后每个球队向汇点连一条边,流量即为该球队胜场的限制.
#include<cstdio> #include<cstring> #include<algorithm> #include<stack> #include<set> #include<vector> #include<cmath> #include<map> #include<queue> #define LL long long using namespace std; const LL mod=1e9+7; const int N=1e3+5; const int inf=0x3f3f3f3f; struct node { int to,cap,next,flow; node(){} node(int to,int cap,int next,int flow):to(to),cap(cap),next(next),flow(flow){} }edge[N<<2]; int tol; int head ,gap ,dep ,pre ,cur ; int win ,r ,a ; void init() { tol=0; memset(head,-1,sizeof(head)); } void addedge(int u,int v,int w,int rw=0) { edge[tol]=node(v,w,head[u],0); head[u]=tol++; edge[tol]=node(u,rw,head[v],0); head[v]=tol++; } int sap(int start,int _end,int N) { memset(gap,0,sizeof(gap)); memset(dep,0,sizeof(dep)); memcpy(cur,head,sizeof(head)); int u=start; pre[u]=-1; gap[0]=N; int ans=0; while(dep[start]<N) { if(u==_end) { int Min=inf; for(int i=pre[u];i!=-1;i=pre[edge[i^1].to]) if(Min>edge[i].cap-edge[i].flow) Min=edge[i].cap-edge[i].flow; for(int i=pre[u];i!=-1;i=pre[edge[i^1].to]) { edge[i].flow+=Min; edge[i^1].flow-=Min; } u=start; ans+=Min; continue; } bool flag=false; int v; for(int i=cur[u];i!=-1;i=edge[i].next) { v=edge[i].to; if(edge[i].cap-edge[i].flow&&dep[v]+1==dep[u]) { flag=true; cur[u]=pre[v]=i; break; } } if(flag) { u=v; continue; } int Min=N; for(int i=head[u];i!=-1;i=edge[i].next) if(edge[i].cap-edge[i].flow&&dep[edge[i].to]<Min) { Min=dep[edge[i].to]; cur[u]=i; } gap[dep[u]]--; if(!gap[dep[u]])return ans; dep[u]=Min+1; gap[dep[u]]++; if(u!=start)u=edge[pre[u]^1].to; } return ans; } int main() { //freopen("a.txt","r",stdin); int n; while(~scanf("%d",&n)) { init(); for(int i=1;i<=n;i++)scanf("%d",&win[i]); for(int i=1;i<=n;i++)scanf("%d",&r[i]); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&a[i][j]); int temp=win[1]+r[1]; int flag=1; for(int i=2;i<=n;i++) if(win[i]>temp)flag=0; if(flag==0) { puts("NO");continue; } int cnt=0,sum=0; for(int i=2;i<=n;i++) { for(int j=i;j<=n;j++) { cnt++;sum+=a[i][j]; addedge(0,cnt,a[i][j]); addedge(cnt,i-1+n*(n-1)/2,inf); addedge(cnt,j-1+n*(n-1)/2,inf); } } for(int i=2;i<=n;i++) addedge(i-1+n*(n-1)/2,n*(n+1)/2,temp-win[i]); int ans=sap(0,n*(n+1)/2,n*(n+1)/2+1); if(ans==sum)puts("YES"); else puts("NO"); } return 0; }
相关文章推荐
- Poj2638 网络流+最短路+二分答案
- BZOJ3275 Number (最小割)
- [笔记] 网络流-最大流 POJ-1273\HDU-4240
- 上下界网络流初探
- Edmonds-Karp 最大流 hdu 1532 Drained Ditches
- 网络流_poj1273
- POJ 1273 Drainage Ditches 最大流 dinic
- POJ1273-Drainage Ditches
- 【网络流】复杂的大门
- ACM/ICPC World Finals 2013 C Surely You Congest
- 北京集训队 2016 Day4 alarm
- 网络流算法整理
- 网络流最大流之SAP算法 详解
- [BZOJ1797][AHOI2009][最大流][强连通分量]Mincut最小割
- [BZOJ2324][ZJOI2011][最小费用最大流]营救皮卡丘
- [BZOJ1834][ZJOI2010][最大流][最小费用最大流]网络扩容
- Topcoder SRM642 TaroCutting
- POJ2391解题报告
- uva 11248
- 【学习】网络流