zoukankan      html  css  js  c++  java
  • 【BZOJ】【3504】【CQOI2014】危桥

    网络流/最大流


      比较裸的最大流= =

      无向图上走来回其实就等价与走两遍>_>

      如果路径有相交其实不影响答案的

      比较恶心的是两个人路过同一座桥,但走的方向不同互相抵消流量了……

      其实只要在第一遍跑网络流以后如果为Yes,就将其中一人的起点终点交换,再跑一遍就可以了

    UPD:其实N=55就可以了,不需要像我代码里那样开到3000……因为只有n个点= =不是$n^2$的

      1 /**************************************************************
      2     Problem: 3504
      3     User: Tunix
      4     Language: C++
      5     Result: Accepted
      6     Time:44 ms
      7     Memory:2500 kb
      8 ****************************************************************/
      9  
     10 //BZOJ 3504
     11 #include<vector>
     12 #include<cstdio>
     13 #include<cstring>
     14 #include<cstdlib>
     15 #include<iostream>
     16 #include<algorithm>
     17 #define rep(i,n) for(int i=0;i<n;++i)
     18 #define F(i,j,n) for(int i=j;i<=n;++i)
     19 #define D(i,j,n) for(int i=j;i>=n;--i)
     20 #define pb push_back
     21 using namespace std;
     22 inline int getint(){
     23     int v=0,sign=1; char ch=getchar();
     24     while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();}
     25     while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();}
     26     return v*sign;
     27 }
     28 const int N=3010,M=1e5+10,INF=~0u>>2;
     29 typedef long long LL;
     30 /******************tamplate*********************/
     31 int n,m,tot,ans,a1,a2,an,b1,b2,bn;
     32 char mp[55][55];
     33 struct edge{int to,v;};
     34 struct Net{
     35     edge E[M];
     36     int head[N],next[M],cnt;
     37     void ins(int x,int y,int v){
     38         E[++cnt]=(edge){y,v};
     39         next[cnt]=head[x]; head[x]=cnt;
     40     }
     41     void add(int x,int y,int v){
     42         ins(x,y,v); ins(y,x,0);
     43     }
     44     int s,t,cur[N],d[N],Q[N];
     45     bool mklevel(){
     46         memset(d,-1,sizeof d);
     47         d[s]=0;
     48         int l=0,r=-1;
     49         Q[++r]=s;
     50         while(l<=r){
     51             int x=Q[l++];
     52             for(int i=head[x];i;i=next[i])
     53                 if (d[E[i].to]==-1 && E[i].v){
     54                     d[E[i].to]=d[x]+1;
     55                     Q[++r]=E[i].to;
     56                 }
     57         }
     58         return d[t]!=-1;
     59     }
     60     int dfs(int x,int a){
     61         if (x==t) return a;
     62         int flow=0;
     63         for(int &i=cur[x];i && flow<a;i=next[i])
     64             if (E[i].v && d[E[i].to]==d[x]+1){
     65                 int f=dfs(E[i].to,min(a-flow,E[i].v));
     66                 E[i].v-=f;
     67                 E[i^1].v+=f;
     68                 flow+=f;
     69             }
     70         if (!flow) d[x]=-1;
     71         return flow;
     72     }
     73     void Dinic(){
     74         while(mklevel()){ 
     75             F(i,s,t) cur[i]=head[i];
     76             ans+=dfs(s,INF);
     77         }
     78     }
     79     void init(){
     80         s=0; t=n+1; cnt=1; ans=0;
     81         memset(head,0,sizeof head);
     82         F(i,1,n){
     83             scanf("%s",mp[i]+1);
     84             F(j,1,n){
     85                 if (mp[i][j]=='N') add(i,j,INF);
     86                 else if (mp[i][j]=='O') add(i,j,2);
     87             }
     88         }
     89         add(s,a1+1,an*2); add(a2+1,t,an*2);
     90         add(s,b1+1,bn*2); add(b2+1,t,bn*2);
     91         Dinic();
     92         if (ans==an*2+bn*2){
     93             cnt=1; memset(head,0,sizeof head);
     94             F(i,1,n) F(j,1,n){
     95                 if (mp[i][j]=='N') add(i,j,INF);
     96                 else if (mp[i][j]=='O') add(i,j,2);
     97             }
     98             add(s,a1+1,an*2); add(a2+1,t,an*2);
     99             add(s,b2+1,bn*2); add(b1+1,t,bn*2);
    100             ans=0; Dinic();
    101             if (ans==an*2+bn*2) puts("Yes");
    102             else puts("No");
    103         }else puts("No");
    104     }
    105 }G1;
    106  
    107 int main(){
    108 #ifndef ONLINE_JUDGE
    109     freopen("3504.in","r",stdin);
    110     freopen("3504.out","w",stdout);
    111 #endif
    112     while(scanf("%d%d%d%d%d%d%d",&n,&a1,&a2,&an,&b1,&b2,&bn)!=EOF)
    113         G1.init();
    114     return 0;
    115 }
    View Code

    3504: [Cqoi2014]危桥

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 588  Solved: 313
    [Submit][Status][Discuss]

    Description

    Alice和Bob居住在一个由N座岛屿组成的国家,岛屿被编号为0到N-1。某些岛屿之间有桥相连,桥上的道路是双
    向的,但一次只能供一人通行。其中一些桥由于年久失修成为危桥,最多只能通行两次。Alice希望在岛屿al和a2之间往返an次(从al到a2再从a2 到al算一次往返)。同时,Bob希望在岛屿bl和b2之间往返bn次。这个过程中,所有危桥最多通行两次,其余的桥可以无限次通行。请问Alice和 Bob能完成他们的愿望吗?

    Input


    本题有多组测试数据。
    每组数据第一行包含7个空格隔开的整数,分别为N、al、a2、an、bl、b2、bn。
    接下来是一个N行N列的对称矩阵,由大写字母组成。矩阵的i行j列描述编号i一1和j-l的岛屿间的连接情况,若为“O”则表示有危桥相连:为“N”表示有普通的桥相连:为“X”表示没有桥相连。
    |

    Output

    对于每组测试数据输出一行,如果他们都能完成愿望输出“Yes”,否则输出“No”。


    Sample Input

    4 0 1 1 2 3 1
    XOXX
    OXOX
    XOXO
    XXOX
    4 0 2 1 1 3 2
    XNXO
    NXOX
    XOXO
    OXOX

    Sample Output

    Yes
    No
    数据范围
    4<=N<50
    O<=a1, a2, b1, b2<=N-1
    1 <=an. b<=50

    HINT

    Source

    [Submit][Status][Discuss]
  • 相关阅读:
    欧拉公式
    isap的一些想法
    错误合集
    Hello World
    PAT (Advanced Level) Practice 1068 Find More Coins
    PAT (Advanced Level) 1087 All Roads Lead to Rome
    PAT (Advanced Level) 1075 PAT Judge
    PAT (Advanced Level) 1067 Sort with Swap(0, i)
    PAT (Advanced Level) 1017 Queueing at Bank
    PAT (Advanced Level) 1025 PAT Ranking
  • 原文地址:https://www.cnblogs.com/Tunix/p/4421099.html
Copyright © 2011-2022 走看看