zoukankan      html  css  js  c++  java
  • BZOJ 1934: [Shoi2007]Vote 善意的投票

    BZOJ 1934: [Shoi2007]Vote 善意的投票

    标签(空格分隔): OI-BZOJ OI-最小割


    Time Limit: 1 Sec
    Memory Limit: 64 MB


    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

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


    Solution####

    最小割,i睡觉S就向i连容量为1的边,否则i向T连容量为1的边,若2个人是好朋友,就在2人间连容量为1的无向边,跑一边最小割=最大流


    Code####

    #include<iostream>
    #include<stdio.h>
    #include<math.h>
    #include<stdlib.h>
    #include<string.h>
    #include<algorithm>
    #include<queue>
    using namespace std;
    int read()
    {
    	int s=0,f=1;char ch=getchar();
    	while(!('0'<=ch&&ch<='9')){if(ch=='-')f=-1;ch=getchar();}
    	while('0'<=ch&&ch<='9'){s=(s<<3)+(s<<1)+ch-'0';ch=getchar();}
    	return s*f;
    }
    int S,T,n,m,np;
    int A[305];
    int be[100005],bn[200005],bv[200005],bl[200005],bw=1;
    void put(int u,int v,int l)
    {bw++;bn[bw]=be[u];be[u]=bw;bv[bw]=v;bl[bw]=l;}
    int d[100005];
    bool spfa(int S,int T)
    {
    	for(int i=1;i<=np;i++)
    	   d[i]=10000000;
    	d[S]=1;
    	queue<int>q;
    	for(q.push(S);!q.empty();)
    	   {int u=q.front();q.pop();
    	    for(int i=be[u],v;i;i=bn[i])
    	       if(d[v=bv[i]]>d[u]+1&&bl[i])
    	         {d[v]=d[u]+1;
    	          q.push(v);
    			 }
    	   }
    	return d[T]!=10000000;
    }
    int ans;
    int dinic(int u,int mf,int T)
    {
    	if(mf==0)return 0;
    	if(u==T)return mf;
    	int sum=0;
    	for(int i=be[u],v;i;i=bn[i])
    	   if(d[v=bv[i]]==d[u]+1)
    	     {int f=dinic(v,min(mf-sum,bl[i]),T);
    	      bl[i]-=f;
    	      bl[i^1]+=f;
    	      sum+=f;
    	     }
    	return sum;
    }
    int main()
    {
    	n=read();m=read();
    	S=++np,T=++np;
    	for(int i=1;i<=n;i++)
    	   {A[i]=++np;
    	    if(read())
    	      put(S,A[i],1),
    	      put(A[i],S,0);
    	    else
    	      put(A[i],T,1),
    	      put(T,A[i],0);
    	   }
    	for(int i=1;i<=m;i++)
    	   {int u=read(),v=read();
    	    put(A[u],A[v],1),
    		put(A[v],A[u],1);
    	   }
    	while(spfa(S,T))ans+=dinic(S,1e9,T);
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    SQL update select
    Centos7 update dotnet 无法识别
    asp.net core mvc 在中间件中使用依赖注入问题:System.InvalidOperationException: Cannot resolve scoped service 'IXXXService' from root provider.
    SQL Server类型与C#类型对应关系
    .NET Core ABP
    支付宝小程序获取用户授权
    .Net 多线程,异步且控制并发数量
    SQL:尝试将不可为 NULL 的列的值设置为 NULL
    .Net Core依赖注入和服务注册
    .NET Core配置主机端口的几种方式
  • 原文地址:https://www.cnblogs.com/wuyuhan/p/5242344.html
Copyright © 2011-2022 走看看