• BZOJ_1934_[Shoi2007]Vote 善意的投票


    BZOJ_1934_[Shoi2007]Vote 善意的投票

    Description

    幼儿园里有n个小朋友打算通过投票来决定睡不睡午觉。对他们来说,这个问题并不是很重要,于是他们决定发扬谦让精神。虽然每个人都有自己的主见,但是为了照顾一下自己朋友的想法,他们也可以投和自己本来意愿相反的票。我们定义一次投票的冲突数为好朋友之间发生冲突的总数加上和所有和自己本来意愿发生冲突的人数。 我们的问题就是,每位小朋友应该怎样投票,才能使冲突数最小?

    Input

    第一行只有两个整数n,m,保证有2≤n≤300,1≤m≤n(n-1)/2。其中n代表总人数,m代表好朋友的对数。文件第二行有n个整数,第i个整数代表第i个小朋友的意愿,当它为1时表示同意睡觉,当它为0时表示反对睡觉。接下来文件还有m行,每行有两个整数i,j。表示i,j是一对好朋友,我们保证任何两对i,j不会重复。

    Output

    只需要输出一个整数,即可能的最小冲突数。

    Sample Input

    3 3
    1 0 0
    1 2
    1 3
    3 2

    Sample Output

    1
     

    设源点S,汇点T,S向意愿为1的人连边,意愿为0的人向T连边。
    割这些边表示投意愿相反的票。
    每个人向朋友连边,割这些边表示和朋友发生冲突。
    求最小割即可。
     
    代码:
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    #define inf 100000000
    #define S (n+1)
    #define T (n+2)
    #define N 350
    #define M 500050
    int head[N],to[M],nxt[M],flow[M],cnt=1,n,m,dep[N];
    int Q[N],l,r;
    inline void add(int u,int v,int f) {
        to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt; flow[cnt]=f;
        to[++cnt]=u; nxt[cnt]=head[v]; head[v]=cnt; flow[cnt]=0;
    }
    bool bfs() {
        int i;
        memset(dep,0,sizeof(dep));
        dep[S]=1;
        l=r=0;
        Q[r++]=S;
        while(l<r) {
            int x=Q[l++];
            for(i=head[x];i;i=nxt[i]) {
                if(!dep[to[i]]&&flow[i]) {
                    dep[to[i]]=dep[x]+1;
                    if(to[i]==T) return 1;
                    Q[r++]=to[i];
                }
            }
        }
        return 0;
    }
    int dfs(int x,int mf) {
        if(x==T) return mf;
        int nf=0,i;
        for(i=head[x];i;i=nxt[i]) {
            if(dep[to[i]]==dep[x]+1&&flow[i]) {
                int tmp=dfs(to[i],min(mf-nf,flow[i]));
                nf+=tmp;
                flow[i]-=tmp;
                flow[i^1]+=tmp;
                if(nf==mf) break;
            }
        }
        dep[x]=0;
        return nf;
    }
    void dinic() {
        int ans=0,f;
        while(bfs())while(f=dfs(S,inf))ans+=f;
        printf("%d
    ",ans);
    }
    int main() {
        scanf("%d%d",&n,&m);
        int i,x,y;
        for(i=1;i<=n;i++) {
            scanf("%d",&x);
            if(x) add(S,i,1);
            else add(i,T,1);
        }
        for(i=1;i<=m;i++) {
            scanf("%d%d",&x,&y);
            add(x,y,1);
            add(y,x,1);
        }
        dinic();
    }
    

     

  • 相关阅读:
    App调试的几个命令实践【转】
    解决sdk更新时候报错 http://dl-ssl.google.com/android上不去,链接拒绝
    fastjson序列化排序问题
    Java中的四种引用
    equal&==&hashcode
    ThreadPool线程池的关注点
    JVM的本地方法栈
    JVM的堆分配
    JVM的类装载子系统
    JVM的数据类型
  • 原文地址:https://www.cnblogs.com/suika/p/8742672.html
Copyright © 2020-2023  润新知