zoukankan      html  css  js  c++  java
  • [SHOI2007]善意的投票

    题目描述

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

    我们的问题就是,每位小朋友应该怎样投票,才能使冲突数最小?

    题解

    一开始往二元关系那块想然后发现做不了。

    其实正解做法很简单,我们把要睡觉的连s,不睡觉的连t,朋友之间连双向边,图的最小割就是答案。

    我们设割集为S,那么如果割集出现了s-x的边或x-t的边说明这个人改变主意了,如果出现了x-y的边说明最佳方案中这两个人冲突了。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #define N 309
    using namespace std;
    queue<int>q;
    int n,m,head[N],tot=1,deep[N],ans;
    struct edge{
        int n,to,l;
    }e[N*N];
    inline int rd(){
        int x=0;char c=getchar();bool f=0;
        while(!isdigit(c)){if(c=='-')f=1;c=getchar();}
        while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
        return f?-x:x;
    }
    inline void add(int u,int v,int l,int l2){
        e[++tot].n=head[u];e[tot].to=v;head[u]=tot;e[tot].l=l;
        e[++tot].n=head[v];e[tot].to=u;head[v]=tot;e[tot].l=l2;
    }
    inline bool bfs(int s,int t){
        memset(deep,0,sizeof(deep));
        q.push(s);deep[s]=0;
        while(!q.empty()){
            int u=q.front();q.pop();
            for(int i=head[u];i;i=e[i].n){
                int v=e[i].to;
                if(!deep[v]&&e[i].l){
                    deep[v]=deep[u]+1;
                    q.push(v);
                }
            }
        }
        return deep[t];
    }
    int dfs(int u,int t,int l){
        if(u==t||!l)return l;
        int f,flow=0;
        for(int i=head[u];i;i=e[i].n){
            int v=e[i].to;
            if(deep[v]==deep[u]+e[i].l&&(f=dfs(v,t,min(l,e[i].l)))){
                e[i].l-=f;e[i^1].l+=f;flow+=f;l-=f;
                if(!l)break;
            }    
        }
        return flow;
    }
    int main(){
        n=rd();m=rd();int u,v,x;
        for(int i=1;i<=n;++i){
            x=rd();
            if(x)add(i,n+1,1,0);else add(0,i,1,0);
        }
        for(int i=1;i<=m;++i){
            u=rd();v=rd();
            add(u,v,1,1);
        }
        while(bfs(0,n+1))ans+=dfs(0,n+1,1e9);
        cout<<ans;
        return 0;
    } 
  • 相关阅读:
    hive中使用正則表達式不当导致执行奇慢无比
    C/C++实现正负数四舍五入
    EEPlat的控制器概念
    由于好高骛远所以半途而废(张作作)
    新辰:关于“网络推广不能仅仅依靠网络”的详解
    SQL的事务回滚操作带案例分析
    怎样把引用的jar包和本项目一起导出成jar文件
    A星算法(Java实现)
    Hadoop之——HBASE结合MapReduce批量导入数据
    Spring MVC 数据验证——validate编码方式
  • 原文地址:https://www.cnblogs.com/ZH-comld/p/10505384.html
Copyright © 2011-2022 走看看