zoukankan      html  css  js  c++  java
  • BZOJ2768 JLOI2012冠军调查(最小割)

      容易想到网络流。将每个人拆成0和1两个点。若某人值为0的话则让源连向0,否则让1连向汇,流量为1。相互认识的人之间01各自连边。跑最小割即可。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    #define N 310 
    #define S 0
    #define T 601
    int n,m,p[N<<1],t=-1,ans=0;
    int d[N<<1],cur[N<<1],q[N<<1];
    struct data{int to,nxt,cap,flow;
    }edge[N*N<<1];
    int trans(int x,int y){return (x<<1)-y;}
    void addedge(int x,int y)
    {
        t++;edge[t].to=y,edge[t].nxt=p[x],edge[t].cap=1,edge[t].flow=0,p[x]=t;
        t++;edge[t].to=x,edge[t].nxt=p[y],edge[t].cap=0,edge[t].flow=0,p[y]=t;
    }
    bool bfs()
    {
        memset(d,255,sizeof(d));d[S]=0;
        int head=0,tail=1;q[1]=S;
        do
        {
            int x=q[++head];
            for (int i=p[x];~i;i=edge[i].nxt)
            if (d[edge[i].to]==-1&&edge[i].flow<edge[i].cap)
            {
                d[edge[i].to]=d[x]+1;
                q[++tail]=edge[i].to;
            }
        }while (head<tail);
        return ~d[T];
    }
    int work(int k,int f)
    {
        if (k==T) return f;
        int used=0;
        for (int i=cur[k];~i;i=edge[i].nxt)
        if (d[k]+1==d[edge[i].to])
        {
            int w=work(edge[i].to,min(f-used,edge[i].cap-edge[i].flow));
            edge[i].flow+=w,edge[i^1].flow-=w;
            if (edge[i].flow<edge[i].cap) cur[k]=i;
            used+=w;if (used==f) return f;
        }
        if (used==0) d[k]=-1;
        return used;
    }
    void dinic()
    {
        while (bfs())
        {
            memcpy(cur,p,sizeof(p));
            ans+=work(S,N*N);
        }
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("bzoj2768.in","r",stdin);
        freopen("bzoj2768.out","w",stdout);
        const char LL[]="%I64d
    ";
    #else
        const char LL[]="%lld
    ";
    #endif
        n=read(),m=read();
        memset(p,255,sizeof(p));
        for (int i=1;i<=n;i++)
        {
            int x=read();
            if (x) addedge(trans(i,1),T);
            else addedge(S,trans(i,0));
        }
        for (int i=1;i<=m;i++)
        {
            int x=read(),y=read();
            addedge(trans(x,0),trans(y,1));
            addedge(trans(y,0),trans(x,1));
        }
        dinic();
        cout<<ans;
        return 0;
    }
  • 相关阅读:
    yii 引入文件
    CodeForces 621C Wet Shark and Flowers
    面试题题解
    POJ 2251 Dungeon Master
    HDU 5935 Car(模拟)
    HDU 5938 Four Operations(暴力枚举)
    CodeForces 722C Destroying Array(并查集)
    HDU 5547 Sudoku(dfs)
    HDU 5583 Kingdom of Black and White(模拟)
    HDU 5512 Pagodas(等差数列)
  • 原文地址:https://www.cnblogs.com/Gloid/p/9625097.html
Copyright © 2011-2022 走看看