• bzoj3504[Cqoi2014]危桥


    bzoj3504[Cqoi2014]危桥

    题意:

    有N座岛屿,某些岛屿之间有桥相连,桥上的道路是双向的,但一次只能供一人通行。其中一些桥是危桥。Alice希望在岛屿al和a2之间往返an次(从al到a2再从a2 到al算一次往返)。同时,Bob希望在岛屿bl和b2之间往返bn次。这个过程中,所有危桥最多通行两次,其余的桥可以无限次通行。判断两人能否达成愿望。

    题解:

    网络流,每天边的容量就是这条边可以走几次,建一个超级源连a1b1,a2b2连超级汇,如果最大流大于等于2*(b1+b2)就行。但有可能出现a1流到b2导致原来的不可行被判断成可行,这样我们就需要把b2和b1调换位置,如果结果一样,说明这个方案是真正可行的,具体原因我还不懂,好像是如果两个结果一样,即使真的出现了a1流到b2的情况,也能通过调整变成正确的流动方案,蒟蒻太弱了!

    代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <queue>
     5 #define INF 0x3fffffff
     6 #define inc(i,j,k) for(int i=j;i<=k;i++)
     7 using namespace std;
     8 
     9 struct e{int t,c,n;}; e es[10000]; int ess,g[100];
    10 void pe(int f,int t,int c){es[++ess]=(e){t,c,g[f]}; g[f]=ess; es[++ess]=(e){f,0,g[t]}; g[t]=ess;}
    11 char map[100][100]; int n,a1,a2,an,b1,b2,bn,s,t;
    12 queue <int> q; int h[100];
    13 bool bfs(int s,int t){
    14     while(! q.empty())q.pop(); memset(h,-1,sizeof(h)); h[s]=0; q.push(s);
    15     while(! q.empty()){
    16         int x=q.front(); q.pop();
    17         for(int i=g[x];i!=-1;i=es[i].n)if(es[i].c&&h[es[i].t]==-1)h[es[i].t]=h[x]+1,q.push(es[i].t);
    18     }
    19     if(h[t]==-1)return 0;else return 1;
    20 }
    21 int dfs(int x,int t,int f){
    22     if(x==t)return f; int u=0;
    23     for(int i=g[x];i!=-1;i=es[i].n)if(es[i].c&&h[es[i].t]==h[x]+1){
    24         int w=dfs(es[i].t,t,min(f,es[i].c)); es[i].c-=w; es[i^1].c+=w; f-=w; u+=w;
    25         if(f==0)return u;
    26     }
    27     if(u==0)h[x]=-1; return u;
    28 }
    29 int dinic(int s,int t){int f=0; while(bfs(s,t))f+=dfs(s,t,INF); return f;}
    30 int main(){
    31     while(scanf("%d%d%d%d%d%d%d",&n,&a1,&a2,&an,&b1,&b2,&bn)!=EOF){
    32         inc(i,1,n)scanf("%s",map[i]); a1++; a2++; b1++; b2++; s=0; t=n+1;
    33         ess=-1; memset(g,-1,sizeof(g)); pe(s,a1,2*an); pe(s,b1,2*bn); pe(a2,t,2*an); pe(b2,t,2*bn);
    34         inc(i,1,n)inc(j,0,n-1){
    35             if(map[i][j]=='O')pe(i,j+1,2);
    36             if(map[i][j]=='N')pe(i,j+1,INF);
    37         }
    38         if(dinic(s,t)>=2*an+2*bn){
    39             ess=-1; memset(g,-1,sizeof(g)); pe(s,a1,2*an); pe(s,b2,2*bn); pe(a2,t,2*an); pe(b1,t,2*bn);
    40             inc(i,1,n)inc(j,0,n-1){
    41                 if(map[i][j]=='O')pe(i,j+1,2);
    42                 if(map[i][j]=='N')pe(i,j+1,INF);
    43             }
    44             if(dinic(s,t)>=2*an+2*bn)printf("Yes
    ");else printf("No
    ");
    45         }else printf("No
    ");
    46     }
    47     return 0;
    48 }

    20160408

  • 相关阅读:
    机房管理系统
    Red_Black_Tree C++
    Binary_Seach_Tree(BST) C++
    贪吃蛇小笔记
    转-Unix系统进程对SIGTERM、SIGUSR1和SIGUSR2信号处理
    My Dev Env
    mac gdb home-brew
    pub python
    ioctl siocgifhwaddr mac os x
    macbook与外接显示器
  • 原文地址:https://www.cnblogs.com/YuanZiming/p/5697031.html
Copyright © 2020-2023  润新知