3504: [Cqoi2014]危桥 最大流

读完题的感觉就是网络流啦。S连向俩起点,俩终点连向T。
然而会有一个bug。
比如a1有x流到了b2,而b1有x流到了a2。这样最后也是满流,但其实是不合乎条件的。
我们可以把b1,b2调换一下位置再跑一遍,如果还是满流那么就合乎题意啦。

#include<iostream>
#include<cstdio>
#include<cstring>
#define inf 1000000007
using namespace std;
int n,T,cnt,ans;
int a[55][55];
int head[55],q[55],dis[55];
int next[5005],key[5005],list[5005];
inline int read()
{
    int a=0,f=1; char c=getchar();
    while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
    while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
    return a*f;
}
inline void insert(int x,int y,int z)
{
    next[++cnt]=head[x];
    head[x]=cnt;
    list[cnt]=y;
    key[cnt]=z;
}
inline void build()
{
    memset(head,0,sizeof(head)); cnt=1;
    for (int i=1;i<=n;i++)
        for (int j=1;j<=n;j++)
            if (a[i][j]==1) insert(i,j,2),insert(j,i,0);
            else if (a[i][j]==2) insert(i,j,inf),insert(j,i,0);
}
inline bool BFS()
{
    memset(dis,-1,sizeof(dis));
    dis[0]=1; q[1]=0;
    int t=0,w=1,x;
    while (t!=w)
    {
        x=q[++t];
        for (int i=head[x];i;i=next[i])
            if (key[i]&&dis[list[i]]==-1)
                dis[list[i]]=dis[x]+1,q[++w]=list[i];
    }
    return dis[T]!=-1;
}
int find(int x,int flow)
{
    if (x==T) return flow;
    int w,used=0;
    for (int i=head[x];i;i=next[i])
        if (key[i]&&dis[list[i]]==dis[x]+1)
        {
            w=find(list[i],min(key[i],flow-used));
            key[i]-=w; key[i^1]+=w; used+=w;
            if (used==flow) return flow;
        }
    if (!used) dis[x]=-1;
    return used;
}
inline void dinic()
{
    ans=0;
    while (BFS()) ans+=find(0,inf);
}
int main()
{
    while (scanf("%d",&n)!=EOF)
    {
        memset(a,0,sizeof(a)); T=n+1; 
        int a1,a2,an,b1,b2,bn,flag=1;
        char s[55];
        a1=read()+1; a2=read()+1; an=read();
        b1=read()+1; b2=read()+1; bn=read();
        for (int i=1;i<=n;i++)
        {
            scanf("%s",s+1);
            for (int j=1;j<=n;j++)
                if (s[j]=='O') a[i][j]=1;
                else if (s[j]=='N') a[i][j]=2;
        }
        build();
        insert(0,a1,an*2); insert(a1,0,0);
        insert(0,b1,bn*2); insert(b1,0,0);
        insert(a2,T,inf); insert(T,a2,0);
        insert(b2,T,inf); insert(T,b2,0);
        dinic();
        if (ans<(an+bn)*2) flag=0;
        if (flag)
        {
            build();
            insert(0,a1,an*2); insert(a1,0,0);
            insert(0,b2,bn*2); insert(b2,0,0);
            insert(a2,T,inf); insert(T,a2,0);
            insert(b1,T,inf); insert(T,b1,0);
            dinic();
            if (ans<(an+bn)*2) flag=0;
        }
        flag?puts("Yes"):puts("No");
    }
    return 0;
}

你可能感兴趣的:(3504: [Cqoi2014]危桥 最大流)