• BZOJ 1934: [Shoi2007]Vote 善意的投票 最小割


    1934: [Shoi2007]Vote 善意的投票

    Time Limit: 1 Sec  

    Memory Limit: 256 MB

    题目连接

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

    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

    题意

    题解:

    网络流最小割

    S连同意的,T连不同意的

    然后朋友相互连接

    代码:

    #include<cstdio>
     #include<cstring>
     #include<queue>
     #include<cmath>
     using namespace std;
     const int Ni = 100210;
     const int MAX = 1<<26;
     struct Edge{
         int u,v,c;
         int next;
     }edge[20*Ni];
     int n,m;
     int edn;//边数
     int p[Ni];//父亲
     int d[Ni];
     int sp,tp;//原点,汇点
    
     void addedge(int u,int v,int c)
     {
         edge[edn].u=u; edge[edn].v=v; edge[edn].c=c;
         edge[edn].next=p[u]; p[u]=edn++;
    
         edge[edn].u=v; edge[edn].v=u; edge[edn].c=0;
         edge[edn].next=p[v]; p[v]=edn++;
     }
     int bfs()
     {
         queue <int> q;
         memset(d,-1,sizeof(d));
         d[sp]=0;
         q.push(sp);
         while(!q.empty())
         {
             int cur=q.front();
             q.pop();
             for(int i=p[cur];i!=-1;i=edge[i].next)
             {
                 int u=edge[i].v;
                 if(d[u]==-1 && edge[i].c>0)
                 {
                     d[u]=d[cur]+1;
                     q.push(u);
                 }
             }
         }
         return d[tp] != -1;
     }
     int dfs(int a,int b)
     {
         int r=0;
         if(a==tp)return b;
         for(int i=p[a];i!=-1 && r<b;i=edge[i].next)
         {
             int u=edge[i].v;
             if(edge[i].c>0 && d[u]==d[a]+1)
             {
                 int x=min(edge[i].c,b-r);
                 x=dfs(u,x);
                 r+=x;
                 edge[i].c-=x;
                 edge[i^1].c+=x;
             }
         }
         if(!r)d[a]=-2;
         return r;
     }
    
     int dinic(int sp,int tp)
     {
         int total=0,t;
         while(bfs())
         {
             while(t=dfs(sp,MAX))
             total+=t;
         }
         return total;
     }
     int main()
     {
         int i,u,v,c;
         while(~scanf("%d%d",&n,&m))
         {
             edn=0;//初始化
             memset(p,-1,sizeof(p));
             sp=0;tp=n+1;
             for(int i=1;i<=n;i++)
             {
                 int x;
                 scanf("%d",&x);
                 if(x)addedge(sp,i,1);
                 else addedge(i,tp,1);
             }
             for(int i=1;i<=m;i++)
             {
                 int x,y;
                 scanf("%d%d",&x,&y);
                 addedge(x,y,1);
                 addedge(y,x,1);
             }
             printf("%d
    ",dinic(sp,tp));
         }
         return 0;
     }
  • 相关阅读:
    Vue32 插槽
    Vue30 过度与动画
    Vue35 路由
    Vue31 消息订阅和发布
    Vue34 VueX
    oracle11g中rman基本使用方法
    oracle针对多数据只取最新一条的sql
    oracle大表执行慢的优化方法,Oracle性能突然变慢的解决思路
    windows服务安装启动报错误1053:服务没有及时响应启动或控制请求
    Oracle11gSGA调整方法
  • 原文地址:https://www.cnblogs.com/qscqesze/p/4790080.html
Copyright © 2020-2023  润新知