BZOJ 3504 危桥

Posted on 2016-03-28 17:27  ziliuziliu  阅读(102)  评论(0编辑  收藏  举报

一定注意inf要开的非常大。要不然。。。嘿嘿嘿。

因为流量可能有交叉,那么要b1,b2进行交换再来跑一次。

1A很爽。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define maxv 650
#define maxe 250500
#define inf 9999999999999999
using namespace std;
struct edge
{
    long long v,f,nxt;
}e[maxe];
long long g[maxv],n,a1,a2,an,b1,b2,bn,nume=1,map[55][55],s,t,flag;
long long dis[maxv];
queue <long long> q;
bool vis[maxv];
char ss[55];
void addedge(long long u,long long v,long long f)
{
    e[++nume].v=v;
    e[nume].f=f;
    e[nume].nxt=g[u];
    g[u]=nume;
    e[++nume].v=u;
    e[nume].f=0;
    e[nume].nxt=g[v];
    g[v]=nume;
}
void build(long long type)
{
    memset(g,0,sizeof(g));
    nume=1;
    for (long long i=1;i<=n;i++)
        for (long long j=1;j<=n;j++)
            if (map[i][j]==1) addedge(i,j,2);
            else if (map[i][j]==2) addedge(i,j,inf);
    addedge(s,a1,2*an);addedge(a2,t,2*an);
    if (type==1) {addedge(s,b1,2*bn);addedge(b2,t,2*bn);}
    else {addedge(s,b2,2*bn);addedge(b1,t,2*bn);}
}
bool bfs()
{
    while (!q.empty()) q.pop();
    fill(dis+1,dis+t+1,-1);
    memset(vis,false,sizeof(vis));
    q.push(s);dis[s]=0;vis[s]=true;
    while (!q.empty())
    {
        long long head=q.front();
        q.pop();
        for (long long i=g[head];i;i=e[i].nxt)
        {
            long long v=e[i].v;
            if ((e[i].f) && (vis[v]==false))
            {
                dis[v]=dis[head]+1;
                vis[v]=true;
                q.push(v);
            }
        }
    }
    if (dis[t]==-1) return false;
    return true;
}
long long dinic(long long x,long long low)
{
    if (x==t) return low;
    else
    {
        long long ret=0;
        for (long long i=g[x];i;i=e[i].nxt)
        {
            long long v=e[i].v;
            if ((e[i].f) && (dis[v]==dis[x]+1))
            {
                long long dd=dinic(v,min(low,e[i].f));
                e[i].f-=dd;e[i^1].f+=dd;
                ret+=dd;low-=dd;
            }
        }
        if (ret==0) dis[x]=-1;
        return ret;
    }
}
void work(long long type)
{
    long long ret=0;
    build(type);
    while (bfs())
        ret+=dinic(s,inf);
    if (ret==an*2+bn*2) flag=1;
    else flag=0;
}
int main()
{
    while (scanf("%lld%lld%lld%lld%lld%lld%lld",&n,&a1,&a2,&an,&b1,&b2,&bn)!=EOF)
    {
        a1++;a2++;b1++;b2++;
        flag=0;
        memset(map,0,sizeof(map));
        s=0;t=n+1;
        for (long long i=1;i<=n;i++)
        {
            scanf("%s",ss);
            for (long long j=0;j<n;j++)
            {
                if (ss[j]=='O') map[i][j+1]=1;
                else if (ss[j]=='N') map[i][j+1]=2;
            }
        }
        work(1);
        if (flag==1) 
            work(2);
        if (flag==1) printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}