做二手房网站有哪些资料,百度关键词优化手段,就业网站建设总结,web网站开发总结题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id13349 题目大意:有N个球队在同一个赛区,已知他们胜利的场数,还剩下的在赛区内的比赛数和跨赛区的比赛数的和,和在赛区内的比赛对阵矩阵。问&am…
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=13349
题目大意:有N个球队在同一个赛区,已知他们胜利的场数,还剩下的在赛区内的比赛数和跨赛区的比赛数的和,和在赛区内的比赛对阵矩阵。问,1号球队是否可以不小于其余球队胜利场数的最大值。
感觉大牛的思路很好:先贪心一下,让1号球队赢得所有比赛,其余球队输掉所有跨赛区的比赛。如果此时有球队比1号球队胜利场次多,显然直接输出NO。否则,对于在同一赛区的比赛,我们这样构图。新增源点S,汇点T。对于每个点I,从S向I连一条容量为和1号球队胜利场数之差的弧。对于赛区内的每一个进行K次的对阵(I,J),新增一个点P,从I向P连一条容量为K的弧,从J向P连一条容量为K的弧,从P向T连一条容量为K的弧。这样,去一遍最大流,若所有P指向T的弧都满流,则输出YES,否则输出NO。为什么说所有P指向T的弧都满流就是YES的?假设某条P指向T的弧不满流,则S指向I和S指向J的弧已经满流,但是还比赛还没有打完,不管剩下的比赛谁赢都将比1号球队的胜利场次多。所以若所有P指向T的弧都满流,则输出YES,否则输出NO。

1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<algorithm>
5 #include<queue>
6 using namespace std;
7 #define MAXN 1111
8 #define MAXM 1111111
9 #define inf 1<<30
10
11 struct Edge{
12 int v,cap,next;
13 }edge[MAXM];
14
15 int n,vs,vt,NE,NV;
16 int head[MAXN];
17
18 void Insert(int u,int v,int cap)
19 {
20 edge[NE].v=v;
21 edge[NE].cap=cap;
22 edge[NE].next=head[u];
23 head[u]=NE++;
24
25 edge[NE].v=u;
26 edge[NE].cap=0;
27 edge[NE].next=head[v];
28 head[v]=NE++;
29
30 }
31
32 int level[MAXN],gap[MAXN];
33 void bfs(int vt)
34 {
35 memset(level,-1,sizeof(level));
36 memset(gap,0,sizeof(gap));
37 level[vt]=0;
38 gap[0]++;
39 queue<int>que;
40 que.push(vt);
41 while(!que.empty()){
42 int u=que.front();
43 que.pop();
44 for(int i=head[u];i!=-1;i=edge[i].next){
45 int v=edge[i].v;
46 if(level[v]!=-1)continue;
47 level[v]=level[u]+1;
48 gap[level[v]]++;
49 que.push(v);
50 }
51 }
52 }
53
54 int pre[MAXN],cur[MAXN];
55 int SAP(int vs,int vt)
56 {
57 bfs(vt);
58 memset(pre,-1,sizeof(pre));
59 memcpy(cur,head,sizeof(head));
60 int u=pre[vs]=vs,aug=inf,maxflow=0;
61 gap[0]=NV;
62 while(level[vs]<NV){
63 bool flag=false;
64 for(int &i=cur[u];i!=-1;i=edge[i].next){
65 int v=edge[i].v;
66 if(edge[i].cap>0&&level[u]==level[v]+1){
67 flag=true;
68 aug=min(aug,edge[i].cap);
69 pre[v]=u;
70 u=v;
71 if(v==vt){
72 maxflow+=aug;
73 for(u=pre[u];v!=vs;v=u,u=pre[u]){
74 edge[cur[u]].cap-=aug;
75 edge[cur[u]^1].cap+=aug;
76 }
77 aug=inf;
78 }
79 break;
80 }
81 }
82 if(flag)continue;
83 int minlevel=NV;
84 for(int i=head[u];i!=-1;i=edge[i].next){
85 int v=edge[i].v;
86 if(edge[i].cap>0&&level[v]<minlevel){
87 minlevel=level[v];
88 cur[u]=i;
89 }
90 }
91 if(--gap[level[u]]==0)break;
92 level[u]=minlevel+1;
93 gap[level[u]]++;
94 u=pre[u];
95 }
96 return maxflow;
97 }
98
99 int a[44],b[44];
100 int map[44][44];
101 int main()
102 {
103 int sum=0,flag;
104 while(~scanf("%d",&n)){
105 for(int i=1;i<=n;i++)scanf("%d",&a[i]);
106 for(int i=1;i<=n;i++)scanf("%d",&b[i]);
107 for(int i=1;i<=n;i++)
108 for(int j=1;j<=n;j++)
109 scanf("%d",&map[i][j]);
110 sum=a[1]+b[1];
111 flag=0;
112 for(int i=2;i<=n;i++){
113 if(sum<a[i]){
114 flag=1;
115 break;
116 }
117 }
118 if(flag){
119 puts("NO");
120 continue;
121 }
122 vs=0,vt=n*n+n+1,NV=vt+1;
123 NE=0;
124 memset(head,-1,sizeof(head));
125 for(int i=2;i<=n;i++)Insert(vs,i,sum-a[i]);
126 sum=0;
127 for(int i=2;i<=n;i++){
128 for(int j=i+1;j<=n;j++){
129 if(map[i][j]>0){
130 sum+=map[i][j];
131 Insert(i,i*n+j,map[i][j]);
132 Insert(j,i*n+j,map[i][j]);
133 Insert(i*n+j,vt,map[i][j]);
134 }
135 }
136 }
137 if(SAP(vs,vt)==sum){
138 puts("YES");
139 }else
140 puts("NO");
141 }
142 return 0;
143 }
144 View Code
