zoukankan      html  css  js  c++  java
  • bzoj [CQOI2014]危桥

    http://www.lydsy.com/JudgeOnline/problem.php?id=3504

    往返n遍,即单向2*n遍

    危桥流量为2,普通桥流量为inf

    原图跑一遍最大流

    交换b1,b2再跑一遍最大流

    如果两次的结果都等于(an+bn)*2

    则可以

    证明参见http://www.cnblogs.com/chenyushuo/p/5139556.html

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    
    using namespace std;
    
    #define N 100
    #define M 3000
    
    const int inf=1e9;
    
    int n,a1,a2,an,b1,b2,bn;
    
    char s[51][51];
    
    int tot;
    int front[N],nxt[M<<1],to[M<<1],val[M<<1],from[M<<1];
    int lev[N],num[N];
    int path[N];
    int cur[N];
     
    int src,decc;
    
    void read(int &x)
    {
        x=0; char c=getchar();
        while(!isdigit(c))  c=getchar(); 
        while(isdigit(c)) { x=x*10+c-'0'; c=getchar();  }
    }
    
    void add(int u,int v,int w)
    {
        to[++tot]=v; nxt[tot]=front[u]; front[u]=tot; from[tot]=u; val[tot]=w;
        to[++tot]=u; nxt[tot]=front[v]; front[v]=tot; from[tot]=v; val[tot]=0;
    }
    
    void build()
    {
        tot=1;
        memset(front,0,sizeof(front));
        for(int i=1;i<=n;++i)
            for(int j=1;j<=n;++j)
            {
                if(s[i][j]=='O') add(i,j,2);
                else if(s[i][j]=='N') add(i,j,inf);
            }
        src=0; decc=n+1;
        add(src,a1,an<<1);
        add(a2,decc,an<<1);
        add(src,b1,bn<<1);
        add(b2,decc,bn<<1);
    }
    
    bool bfs()
    {
        queue<int>q;
        for(int i=src;i<=decc;++i) lev[i]=decc+1;
        q.push(decc);
        lev[decc]=0;
        int now,t;
        while(!q.empty())
        {
            now=q.front();
            q.pop();
            for(int i=front[now];i;i=nxt[i])
            {
                t=to[i];
                if(lev[t]==decc+1 && val[i^1]) 
                {
                    lev[t]=lev[now]+1;
                    q.push(t);
                }
            }
        }
        return lev[src]!=decc+1;
    }
     
    int augment()
    {
        int now=decc,flow=inf;
        int i;
        while(now!=src)
        {
            i=path[now];
            flow=min(flow,val[i]);
            now=from[i];
        }
        now=decc;
        while(now!=src)
        {
            i=path[now];
            val[i]-=flow;
            val[i^1]+=flow;
            now=from[i];
        }
        return flow;
    }
     
    int isap()
    {
        int flow=0;
        if(!bfs()) return 0;
        memset(num,0,sizeof(num));
        for(int i=src;i<=decc;++i) num[lev[i]]++,cur[i]=front[i];
        int now=src,t;
        while(lev[src]<=decc)
        {
            if(now==decc)
            {
                flow+=augment();
                now=src;
            }
            bool advanced=false;
            for(int i=cur[now];i;i=nxt[i])
            {
                t=to[i];
                if(lev[t]==lev[now]-1 && val[i])
                {
                    advanced=true;
                    path[t]=i;
                    cur[now]=i;
                    now=t;
                    break;
                }
            }
            if(!advanced)
            {
                int mi=decc;
                for(int i=front[now];i;i=nxt[i])
                    if(val[i]) mi=min(mi,lev[to[i]]);
                if(!--num[lev[now]]) break;
                num[lev[now]=mi+1]++;
                cur[now]=front[now];
                if(now!=src) now=from[path[now]];
            }
        }
        return flow;
    }
    
    int main()
    {
        int A,B;
        while(scanf("%d",&n)!=EOF)
        {
            read(a1); read(a2); read(an);
            a1++; a2++;
            read(b1); read(b2); read(bn);
            b1++; b2++;
            for(int i=1;i<=n;++i) scanf("%s",s[i]+1);
            build();
            A=isap();
            if(A!=(an+bn)*2) 
            {
                puts("No");
                continue;
            }
            swap(b1,b2);
            build();
            B=isap();
            puts(A==B ? "Yes" : "No");
        }
    }

    3504: [Cqoi2014]危桥

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 1739  Solved: 868
    [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
  • 相关阅读:
    centos : 创建交换分区
    用法记录
    mysql日志清理
    mysql 通过查看mysql 配置参数、状态来优化你的mysql
    [WPF 自定义控件]Window(窗体)的UI元素及行为
    [WPF 自定义控件]为Form和自定义Window添加FunctionBar
    [WPF 自定义控件]让Form在加载后自动获得焦点
    [WPF 自定义控件]简单的表单布局控件
    [WPF 自定义控件]以Button为例谈谈如何模仿Aero2主题
    [WPF 自定义控件]自定义控件的代码如何与ControlTemplate交互
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8040353.html
Copyright © 2011-2022 走看看