SGU326Perspective(网络流之最大流)(经典竞赛模型)
来源:互联网 发布:qq间谍软件 编辑:程序博客网 时间:2024/06/05 13:27
题目地址:http://acm.sgu.ru/problem.php?contest=0&problem=326
额,这题读错题了。。。又WA了好长时间。。。坚持不看题解也挺浪费时间的。。早点看题解不自己憋着就能早就发现这个傻逼错误了。。。我的错误是把第三行输入的值误认为是只有跨赛区的比赛了,其实后面的括号里很明显写着包括同赛区的比赛。。但是我不认识。。又懒得翻译。。于是这个傻逼错误就诞生了。。。
这题有一种贪心的思想,就是让队伍1的跨赛区比赛尽可能获胜,其他队伍的跨赛区比赛尽可能输。然后算出此时队伍1与其他队伍的积分差值。
建图方法是建立一个源点与一个汇点,把每一场比赛单独看作一个单位,将比赛与源点连边,权值为这场比赛的比赛数。将每场比赛与比赛双方连边,这个权值可以为无限大,只要大于比赛数就可以。最后将每个队与汇点连边,权值为这个队要想不超过队伍1的最大可能分数,即与队伍1的积分差值。最后求最大流是否满流。
代码如下:
#include <iostream>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <math.h>#include <ctype.h>#include <queue>#include <map>#include<algorithm>using namespace std;const int INF=0x3f3f3f3f;int head[500], souce, sink, nv, cnt;int cur[500], num[500], d[500], q[500], p[50], mp[30][30], pre[500];struct node{ int u, v, cap, next;} edge[1000000];void add(int u, int v, int cap){ edge[cnt].v=v; edge[cnt].cap=cap; edge[cnt].next=head[u]; head[u]=cnt++; edge[cnt].v=u; edge[cnt].cap=0; edge[cnt].next=head[v]; head[v]=cnt++;}void bfs(){ memset(num,0,sizeof(num)); memset(d,-1,sizeof(d)); int f1=0, f2=0, i; d[sink]=0; num[0]=1; q[f1++]=sink; while(f1>=f2) { int u=q[f2++]; for(i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(d[v]==-1) { d[v]=d[u]+1; num[d[v]]++; q[f1++]=v; } } }}int isap(){ memcpy(cur,head,sizeof(cur)); bfs(); int flow=0, u=pre[souce]=souce, i; while(d[souce]<nv) { if(u==sink) { int f=INF, pos; for(i=souce;i!=sink;i=edge[cur[i]].v) { if(f>edge[cur[i]].cap) { f=edge[cur[i]].cap; pos=i; } } for(i=souce;i!=sink;i=edge[cur[i]].v) { edge[cur[i]].cap-=f; edge[cur[i]^1].cap+=f; } flow+=f; u=pos; } for(i=cur[u];i!=-1;i=edge[i].next) { if(d[edge[i].v]+1==d[u]&&edge[i].cap) break; } if(i!=-1) { cur[u]=i; pre[edge[i].v]=u; u=edge[i].v; } else { if(--num[d[u]]==0) break; int mind=nv; for(i=head[u];i!=-1;i=edge[i].next) { if(mind>d[edge[i].v]&&edge[i].cap) { mind=d[edge[i].v]; cur[u]=i; } } d[u]=mind+1; num[d[u]]++; u=pre[u]; } } return flow;}int main(){ int n, x, i, j, flag=0, s=0, sum=0, ss; memset(head,-1,sizeof(head)); cnt=0; scanf("%d",&n); for(i=1; i<=n; i++) scanf("%d",&p[i]); scanf("%d",&x); p[1]+=x; for(i=1; i<n; i++) scanf("%d",&x); for(i=2; i<=n; i++) { if(p[i]>p[1]) { flag=1; break; } } if(flag) { printf("NO\n"); } else { for(i=1; i<=n; i++) { for(j=1; j<=n; j++) { scanf("%d",&mp[i][j]); if(mp[i][j]&&i!=1&&j!=1&&j<i) { s++; add(0,s,mp[i][j]); sum+=mp[i][j]; } } } //for(i=1;i<=n;i++) // p[1]+=mp[1][i]; souce=0; sink=s+n+1; nv=sink+1; ss=0; for(i=2;i<=n;i++) { add(s+i,sink,p[1]-p[i]); for(j=2;j<i;j++) { if(mp[i][j]) { ss++; add(ss,i+s,mp[i][j]); add(ss,j+s,mp[i][j]); } } } x=isap(); if(x>=sum) printf("YES\n"); else printf("NO\n"); } return 0;}
2 0
- SGU326Perspective(网络流之最大流)(经典竞赛模型)
- SGU326 Perspective 【网络流 经典竞赛模型】
- ZOJ 3348 Schedule(map运用+网络流之最大流)(竞赛问题升级版)
- hdu3879 网络流(经典最大获利问题)
- poj3155(网络流最大密度子图模型)
- NOI2006最大获利 网络流模型备忘
- 网络流。。。。经典模型。。。HDU2732 && PKU 2711
- (beginer) 网络流(区间模型+最大费用流) UVA 1317 Concert Hall Scheduling
- 网络流之最大流算法(EdmondsKarp)
- POJ 1273Drainage Ditches(网络流之最大流)
- POJ 1459Power Network(网络流之最大流)
- POJ 3281Dining(网络流之最大流)
- HDU 3549Flow Problem(网络流之最大流)
- HDU 3572Task Schedule(网络流之最大流)
- HDU 4280Island Transport(网络流之最大流)
- POJ 1149PIGS(网络流之最大流)
- HDU 2883kebab(网络流之最大流)
- HDU 4292Food(网络流之最大流)
- pre-paid card from Canada
- ubuntu下编译适合ndk的faac
- Android中"再按一次返回键退出程序"的实现(返回桌面)
- [POSIX线程模型]_[使用pthread对工作线程进行简单控制-暂停-继续-停止]
- 去看我房间巧克力我房间开了全局我哭了
- SGU326Perspective(网络流之最大流)(经典竞赛模型)
- Go与C语言的互操作
- 自定义 UITableViewCell 的 accessory 样式(转)
- 文本挖掘之文本表示 - 夜与周公
- 【Leetcode长征系列】Roman to Integer && Integer to Roman
- HUDJ 2011 多项式求和
- 7、Unable to execute dex: Multiple dex files define 解决方法
- MMU作用
- Bitmap,byte[],Drawable相互转化