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

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1934

    题目大意:

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

    解题思路:

    转自:http://hzwer.com/2069.html

    构建源S,汇T
    然后S->一开始投同意的xpy,一开始投反对票的xpy ->T
    流量均为1
    然后对于一个朋友关系(a,b) 添加双向边,流量依然为1
    最后割即为冲突数。
    (1) 冲突数不大于 n:
    很显然,哪怕所有xpy之间都存在朋友关系,xpy可以通过改变(或不改变)原先的决定到达全“同意”或全“否定”,那么朋友之间的冲突数为0,而未被自己先前决定的冲突数不大于n
    (2) “同意”集合和“否定”集合之间的边全部是朋友关系
    (3) 冲突是同意与不同意之间的割

    按我的理解说一下,这样建图完毕后,为什么求的是S->T的最小割。

    一、如果割掉S->i的边那说明这个小朋友违背了自己原本想睡觉的意愿,割掉i->T也是同理,冲突数+1.

    二、如果割掉i->j即同意与不同意两个集合之间的边,则说明两好友意见不同,冲突数+1。

    每个小朋友都要选择同意或者不同意,如果存在S->T的路径,说明有小朋友没有表态,这是不合法的,所以就是求S->T的最小割。

    代码

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<cmath>
      5 #include<algorithm>
      6 #include<queue>
      7 #include<vector>
      8 #define LL long long
      9 #define pii pair<int,int>
     10 #define pll pair<long long,long long>
     11 #define rep(i,a,b) for(int i=a;i<=b;i++)
     12 #define per(i,a,b) for(int i=a;i>=b;i--)
     13 #define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
     14 #define bug cout<<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"<<endl;
     15 #define bugc(_) cout << (#_) << " = " << (_) << endl;
     16 using namespace std;
     17 const int N=1e6+5;
     18 const int M=1e6+5;
     19 const int INF=0x3f3f3f3f;
     20 
     21 struct node{
     22     int to,next,flow;
     23 }edge[M*2]; 
     24 
     25 int cnt,st,en;
     26 int head[N],dep[N];
     27 
     28 void init(){
     29     cnt=2;
     30     memset(head,0,sizeof(head));
     31 }
     32 
     33 void link(int u,int v,int flow){
     34     edge[cnt]=node{v,head[u],flow};
     35     head[u]=cnt++;
     36     edge[cnt]=node{u,head[v],0};
     37     head[v]=cnt++;
     38 }
     39 
     40 int bfs(){
     41     memset(dep,0,sizeof(dep));
     42     dep[st]=1;
     43     queue<int>q;
     44     q.push(st);
     45     while(!q.empty()){
     46         int u=q.front();
     47         q.pop();
     48         for(int i=head[u];i;i=edge[i].next){
     49             node t=edge[i];
     50             if(t.flow&&!dep[t.to]){
     51                 dep[t.to]=dep[u]+1;
     52                 q.push(t.to);
     53             }
     54         }
     55     }
     56     return dep[en]; 
     57 }
     58 
     59 int dfs(int u,int fl){
     60     if(u==en) return fl;
     61     int tmp=0;
     62     for(int i=head[u];i&&fl;i=edge[i].next){
     63         node &t=edge[i];
     64         if(t.flow&&dep[t.to]==dep[u]+1){
     65             int x=dfs(t.to,min(t.flow,fl));
     66             if(x>0){
     67                 t.flow-=x;
     68                 edge[i^1].flow+=x;
     69                 tmp+=x;
     70                 fl-=x;
     71             }
     72         }
     73     }
     74     if(!tmp) dep[u]=-2;
     75     return tmp;
     76 }
     77 
     78 int dinic(){
     79     int ans=0;
     80     while(bfs()){
     81         while(int d=dfs(st,INF)){
     82             ans+=d;
     83         }
     84     }
     85     return ans;
     86 }
     87 
     88 int main(){
     89     int n,m;
     90     while(~scanf("%d%d",&n,&m)){
     91         init();
     92         st=0,en=n+1;
     93         for(int i=1;i<=n;i++){
     94             int x;
     95             scanf("%d",&x);
     96             if(x==1)
     97                 link(st,i,1);
     98             else
     99                 link(i,en,1);
    100         }
    101         for(int i=1;i<=m;i++){
    102             int u,v;
    103             scanf("%d%d",&u,&v);
    104             link(u,v,1);
    105             link(v,u,1);
    106         }
    107         int ans=dinic();
    108         printf("%d
    ",ans);
    109     }
    110     return 0;
    111 }
  • 相关阅读:
    kafka 官方 Quickstart
    oracle11.2 安装
    Perl参考函数/教程
    Mysql参见SHOW命令总结
    MySQL的Innodb缓存相关优化
    Oracle、Mysql和SQL Server数据库连接的URL写法
    jredis 客户端 使用
    sql基本命令-存储过程
    NoSql系列目录ElasticSearch-mongodb
    loadrunner 运行场景-Controller及Load Generators宿主主机优化
  • 原文地址:https://www.cnblogs.com/fu3638/p/9880107.html
Copyright © 2011-2022 走看看