zoukankan      html  css  js  c++  java
  • bzoj3504: [Cqoi2014]危桥(网络流)

    3504: [Cqoi2014]危桥

    题目:传送门 


    题解:

       一开始觉得要跑四次网络流...但是想想好像两次?

       st-->a1/b1  a2/b2-->ed

       好像这样也OK?但是a1流b2或者b1流到a2怎么办?完了...又想错了。

       问了一波zzz大佬,他说我没想错...

       把b1和b2换过来再流一次的话...那原本a1流到b2的流量流到b1再流到a2那不就是相当于a1可以流到a2咯

       每次跑完都看一下流量是不是等于an+bn就好啦。

        


    代码:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<cstdlib>
      4 #include<cmath>
      5 #include<algorithm>
      6 #define inf 999999999
      7 using namespace std;
      8 struct node
      9 {
     10     int x,y,c,next,other;
     11 }a[210000];int len,last[110];
     12 int n,a1,a2,an,b1,b2,bn,st,ed;
     13 void ins(int x,int y,int c)
     14 {
     15     int k1,k2;
     16     k1=++len;
     17     a[len].x=x;a[len].y=y;a[len].c=c;
     18     a[len].next=last[x];last[x]=len;
     19     k2=++len;
     20     a[len].x=y;a[len].y=x;a[len].c=0;
     21     a[len].next=last[y];last[y]=len;
     22 
     23     a[k1].other=k2;
     24     a[k2].other=k1;
     25 }
     26 int list[210000],h[110],head,tail;
     27 bool bt_h()
     28 {
     29     list[1]=st;head=1;tail=2;
     30     memset(h,0,sizeof(h));
     31     h[st]=1;
     32     while(head!=tail)
     33     {
     34         int x=list[head];
     35         for(int k=last[x];k;k=a[k].next)
     36         {
     37             int y=a[k].y;
     38             if(a[k].c>0 && h[y]==0)
     39             {
     40                 h[y]=h[x]+1;
     41                 list[tail++]=y;
     42             }
     43         }
     44         head++;
     45     }
     46     if(h[ed]==0)return false;
     47     return true;
     48 }
     49 int find_flow(int x,int flow)
     50 {
     51     if(x==ed)return flow;
     52     int s=0,t;
     53     for(int k=last[x];k;k=a[k].next)
     54     {
     55         int y=a[k].y;
     56         if(h[y]==h[x]+1 && a[k].c>0 && s<flow)
     57         {
     58             s+=(t=find_flow(y,min(a[k].c,flow-s)));
     59             a[k].c-=t;a[a[k].other].c+=t;
     60         }
     61     }
     62     if(s==0)h[x]=0;
     63     return s;
     64 }
     65 char ss[55][55];
     66 int main()
     67 {
     68     while(scanf("%d%d%d%d%d%d%d",&n,&a1,&a2,&an,&b1,&b2,&bn)!=EOF)
     69     {
     70         len=0;memset(last,0,sizeof(last));
     71         a1++;a2++;b1++;b2++;st=n+1;ed=n+2;int sum=2*an+2*bn;
     72         for(int i=1;i<=n;i++)scanf("%s",ss[i]+1);
     73         
     74         for(int i=1;i<=n;i++)
     75             for(int j=1;j<=n;j++)
     76                 if(ss[i][j]=='N')ins(i,j,inf);
     77                 else if(ss[i][j]=='O')ins(i,j,2);
     78         ins(st,a1,2*an);ins(a2,ed,2*an);
     79         ins(st,b1,2*bn);ins(b2,ed,2*bn);
     80         int ans=0;
     81         while(bt_h())ans+=find_flow(st,inf);
     82         if(ans!=sum){printf("No
    ");continue;}
     83         //反过来 
     84         len=0;memset(last,0,sizeof(last));
     85         for(int i=1;i<=n;i++)
     86             for(int j=1;j<=n;j++)
     87             {
     88                 if(ss[i][j]=='N')ins(i,j,inf);
     89                 else if(ss[i][j]=='O')ins(i,j,2);
     90             }
     91         ins(st,a1,2*an);ins(a2,ed,2*an);
     92         ins(st,b2,2*bn);ins(b1,ed,2*bn);
     93         ans=0;
     94         while(bt_h())ans+=find_flow(st,inf);
     95         
     96         if(ans!=sum){printf("No
    ");continue;}
     97         else printf("Yes
    ");
     98     }
     99     return 0;
    100 }
  • 相关阅读:
    【回溯】数字排列问题
    Price List
    NanoApe Loves Sequence-待解决
    【回溯】n皇后问题
    安卓 学习之旅 入门
    mysql链接 显示 error: 'Access denied for user 'root'@'localhost' (using password: NO)'
    javaweb 实战_1
    java 插件安装
    leetcode 最长有效括号
    hdu 1074 Doing Homework
  • 原文地址:https://www.cnblogs.com/CHerish_OI/p/8644515.html
Copyright © 2011-2022 走看看