zoukankan      html  css  js  c++  java
  • sgu 326(经典网络流构图)

    题目链接: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
  • 相关阅读:
    redis安装
    查看数据库
    redis启动出错Creating Server TCP listening socket 127.0.0.1:6379: bind: No error
    java 面向对象基础
    SpringBoot简单公共返回类
    swift闭包_002_swift闭包
    swift的函数类型_001_swift函数类型基本使用
    swift函数_11_函数的嵌套使用
    swift函数_10_swift中函数基本使用
    swift可选类型_09_optional基本使用
  • 原文地址:https://www.cnblogs.com/wally/p/3319309.html
Copyright © 2011-2022 走看看