zoukankan      html  css  js  c++  java
  • BZOJ 1934善意的投票(最小割) Iscream

    1934: [Shoi2007]Vote 善意的投票

    Time Limit: 1 Sec  Memory Limit: 64 MB
    Submit: 2354  Solved: 1471
    [Submit][Status][Discuss]

    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

    HINT

    在第一个例子中,所有小朋友都投赞成票就能得到最优解

     

    题目链接:

        http://www.lydsy.com/JudgeOnline/problem.php?id=1934 

    Solution

        小朋友的冲突就是割,然后这道题要求的就是最小的割。。。

        从源点向刚开始为1的点连边,从每个刚开始为0的点向汇点连边,每条边容量为1。。。

        然后每一对好朋友之间加一条双向边,容量为1。。。

        都是套路。。。都是套路。。。

    代码

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<iostream>
    #define inf 1000000000
    #define N 10000
    using namespace std;
    inline int Read(){
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    char ch;
    int n,m,S,T,ans;
    int cnt=1;
    int hed[N],h[N],q[N];
    struct edge{
        int r,nxt,v;
    }e[300000];
    void insert(int u,int v,int w){
        e[++cnt].r=v;e[cnt].nxt=hed[u];hed[u]=cnt;e[cnt].v=w;
    }
    bool bfs(){
        int head=0,tail=1,now;
        memset(h,-1,sizeof(h));
        h[S]=1;q[1]=S;
        while(head!=tail){
            head++;now=q[head];
            for(int i=hed[now];i;i=e[i].nxt)
                if(e[i].v&&h[e[i].r]==-1){
                    h[e[i].r]=h[now]+1;
                    q[++tail]=e[i].r;
                }
        }
        return h[T]!=-1;
    }
    int dfs(int x,int F){
        if(x==T) return F;
        int w,used=0;
        for(int i=hed[x];i;i=e[i].nxt)
            if(h[x]+1==h[e[i].r]){
                w=F-used;
                w=dfs(e[i].r,min(w,e[i].v));
                e[i].v-=w;
                e[i^1].v+=w;
                used+=w;
                if(used==F) return F;
            }
        if(!used) h[x]=-1;
        return used;
    }
    void dinic(){
        while( bfs() )
            ans+=dfs(0,inf);
    }
    int main(){
    	int sum=0;
    	int u,v,w;
        n=Read();m=Read();
        S=0;T=n+1;
        for(int i=1;i<=n;i++){
        	w=Read();
        	if(w){
        		insert(S,i,1);
        		insert(i,S,0);
    		}
        	else{
        		insert(i,T,1);
        		insert(T,i,0);
    		}
    	}
    	for(int i=1;i<=m;i++){
    		u=Read();v=Read();
    		insert(u,v,1);
    		insert(v,u,1);
    	}
        dinic();
        printf("%d\n",ans);
        return 0;
    }
    

      

      

    This passage is made by Iscream-2001.

  • 相关阅读:
    类UNIX系统
    wxpython
    新闻
    游戏公司排名
    游戏网站
    3D打印
    python程序报"iccp known incorrect srgb profile" 警告
    python命令行退出
    plc和嵌入式的区别
    要理解互联网的变化轨迹,唯一的方法是弄清背后的规律。“在线”这个所有人既熟悉又陌生的词语,既是常识,也是我一系列想法的核心。
  • 原文地址:https://www.cnblogs.com/Yuigahama/p/7746328.html
Copyright © 2011-2022 走看看