Dinic模板

prwang%%%

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <queue>

using namespace std;

struct Edge { int    to,w,next; }e[110000]; 

int    T,n,m,cnt=1,ver,S,TTT;
int    a[110],p[1100],level[1100];

inline void    Add_edge(const int x,const int y,const int z)
{
    e[++cnt].to=y;
    e[cnt].next=p[x];
    e[cnt].w=z;
    p[x]=cnt;
    return ;
}

bool    Bfs(const int SSS)
{
    int    i,t;
    queue<int>    Q;
    memset(level,0,sizeof(level));
    level[SSS]=1;
    Q.push(SSS);

    while(!Q.empty())
    {
        t=Q.front();Q.pop();
        for(i=p[t];i;i=e[i].next)
        {
            if(!level[e[i].to] && e[i].w)
            {
                level[e[i].to]=level[t]+1;
                Q.push(e[i].to);
            }
        }
    }

    return !!level[TTT];
}

int    Dfs(const int SSS,int    rest)
{
    if(SSS==TTT)return rest;
    const int    back_up=rest;
    for(int i=p[SSS];i;i=e[i].next)
    {
        if(e[i].w && level[e[i].to]==level[SSS]+1)
        {
            int    flow=Dfs(e[i].to,min(rest,e[i].w));
            e[i].w-=flow;
            e[i^1].w+=flow;
            if((rest-=flow)<=0)break;
        }
    }

    if(back_up==rest)level[SSS]=0;
    return back_up-rest;
}

void    Dinic(const int SSS)
{
    while(Bfs(SSS))Dfs(SSS,0x3f3f3f3f);
    return ;
}

int main()
{
    freopen("league.in","r",stdin);
    freopen("league.out","w",stdout);

    int    i,x,y;

    scanf("%d",&T);

    while(T--)
    {
        cnt=1,ver=0;
        memset(p,0,sizeof(p));
        scanf("%d%d",&n,&m);
        for(i=1;i<=n;++i)
        {
            scanf("%d",&a[i]);
        }
        ver=n;
        for(i=1;i<=m;++i)
        {
            scanf("%d%d",&x,&y);
            if(x==n||y==n){a[n]+=2;continue;}
            ver++;
            Add_edge(ver,x,2);
            Add_edge(x,ver,0);
            Add_edge(ver,y,2);
            Add_edge(y,ver,0);
        }

        S=++ver,TTT=++ver;
        for(i=n+1;i<=ver-2;++i)
        {
            Add_edge(S,i,2);
            Add_edge(i,S,0);
        }
        for(i=1;i<=n;++i)
        {
            Add_edge(i,TTT,a[n]-a[i]-1);
            Add_edge(TTT,i,0);
        }

        Dinic(S);

        for(i=p[S];i;i=e[i].next)
        {
            if(e[i].w!=0)
            {
                printf("NO
");
                goto Fail;
            }
        }
        printf("YES
");
Fail:;
    }

    fclose(stdin);
    fclose(stdout);

    return 0;
}
原文地址:https://www.cnblogs.com/Gster/p/4984536.html