牛客多校第一场I1 or 2(网络流)

传送门
源点 s s s 1 1 1,汇点 t t t 2 ∗ n + 2 2*n+2 2n+2
一个点 x i x_i xi拆成 x i 1 , x i 2 x_{i1},x_{i2} xi1,xi2, x i 1 和 1 相 连 , x i 2 和 2 ∗ n + 2 相 连 x_{i1}和1相连,x_{i2}和2*n+2相连 xi11,xi22n+2.
对于边 ( i , j ) (i,j) (i,j),连接 x i 1 x_{i1} xi1 x j 2 x_{j2} xj2 x j 1 x_{j1} xj1 x i 2 x_{i2} xi2.

#include <cstdio>
#include <cstring>
#include <algorithm>
#include<queue>
#include <iostream>
using namespace std;
using std::min;
using std::queue;
#define MAXN 100050
#define MAXM 100005
int n,m,s,t;
struct{
    
    
    int to;
    int val;
    int nxt;
}edge[MAXM*2];
int edgecnt=1;
int head[MAXN];
int vis[MAXN];
int d[MAXN];
void addedge(int u,int v,int w)
{
    
    
    edge[++edgecnt].to=v;
    edge[edgecnt].val=w;
    edge[edgecnt].nxt=head[u];
    head[u]=edgecnt;
}
void init()
{
    
    
    edgecnt=1;
    for(int i=1;i<=2*n+2;i++)
        head[i]=0;
}
bool bfs()
{
    
    
    for(int i=1;i<=2*n+2;i++)
        vis[i]=0;
    vis[s]=1;
    queue<int>q;
    q.push(s);
    while(!q.empty())
    {
    
    
        int now=q.front();q.pop();
        for(int i=head	[now];i;i=edge[i].nxt)
        {
    
    
            if(!vis[edge[i].to]&&edge[i].val)
            {
    
    
                vis[edge[i].to]=vis[now]+1;
                q.push(edge[i].to);
            }
        }
    }
    return vis[t];
}
int dinic(int u,int flow)
{
    
    
    if(u==t)
        return flow;
    int out=0;
    for(int p=head[u];p and flow;p=edge[p].nxt){
    
    
        int v=edge[p].to;
        if(edge[p].val&&vis[u]+1==vis[v])
        {
    
    
            int res=dinic(v,min(flow,edge[p].val));
            edge[p].val-=res;
            edge[p^1].val+=res;
            flow-=res;
            out+=res;
        }
    }
    if(out==0)
        vis[u]=0;
    return out;
}
int main()
{
    
    
    while(scanf("%d%d",&n,&m)==2)
    {
    
    
        init();
        int check=0;
        for(int i=1;i<=n;i++)
            scanf("%d",d+i);
        s=1;
        t=2*n+2;
        for(int i=1;i<=n;i++)
        {
    
    
            int x=2*i;
            check+=d[i];
            addedge(s,x,d[i]);
            addedge(x,s,0);
            addedge(x^1,t,d[i]);
            addedge(t,x^1,0);
        }
        for (int i = 1; i <= m; i++) {
    
    
            int a, b;
            scanf("%d%d", &a, &b);
            int x=2*a;
            int y=2*b;
            addedge(x, y^1, 1);
            addedge(y^1, x, 0);
            addedge(y, x^1, 1);
            addedge(x^1, y, 0);
        }
        int ans = 0;
        while (bfs())
            ans += dinic(s, 2e9);
        if(ans==check)
            printf("YES\n");
        else
            printf("NO\n");
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_43353639/article/details/107303326
今日推荐