zoukankan      html  css  js  c++  java
  • BZOJ1934:[SHOI2007]善意的投票 & BZOJ2768:[JLOI2010]冠军调查——题解

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

    https://www.lydsy.com/JudgeOnline/problem.php?id=2768

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

    最小割模型,S表示睡午觉,T表示不睡,然后连就行了。

    然后这道简单题竟然出现在了两个省选题里面……

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cctype>
    #include<cstdio>
    #include<vector>
    #include<queue>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    const int N=350;
    const int M=N*N+N;
    const int INF=1e9;
    inline int read(){
        int X=0,w=0;char ch=0;
        while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
        while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
        return w?-X:X;
    }
    struct node{
        int nxt,to,w;
    }edge[M];
    int head[N],cnt=-1,S,T;
    void add(int u,int v,int w){
        edge[++cnt].to=v;edge[cnt].w=w;edge[cnt].nxt=head[u];head[u]=cnt;
    }
    int lev[N],cur[N],dui[N];
    bool bfs(int m){
        int r=0;
        for(int i=1;i<=m;i++){
        lev[i]=-1;
        cur[i]=head[i];
        }
        dui[0]=S,lev[S]=0;
        int u,v;
        for(int l=0;l<=r;l++){
        u=dui[l];
        for(int e=head[u];e!=-1;e=edge[e].nxt){
            v=edge[e].to;
            if(edge[e].w>0&&lev[v]==-1){ 
            lev[v]=lev[u]+1;
            r++;
            dui[r]=v; 
            if(v==T)return 1; 
            }
        }
        }
        return 0;
    }
    int dinic(int u,int flow,int m){
        if(u==m)return flow;
        int res=0,delta;
        for(int &e=cur[u];e!=-1;e=edge[e].nxt){
        int v=edge[e].to;
        if(edge[e].w>0&&lev[u]<lev[v]){ 
            delta=dinic(v,min(edge[e].w,flow-res),m); 
            if(delta>0){
            edge[e].w-=delta;
            edge[e^1].w+=delta;
            res+=delta;
            if(res==flow)break; 
            }
        }
        }
        if(res!=flow)lev[u]=-1;
        return res;
    }
    int c[N];
    int main(){
        memset(head,-1,sizeof(head));
        int n=read(),m=read();
        S=n+1,T=S+1;
        for(int i=1;i<=n;i++){
        if(c[i]=read())add(S,i,1),add(i,S,0);
        else add(i,T,1),add(T,i,0);
        }
        for(int i=1;i<=m;i++){
        int a=read(),b=read();
        if(c[b])swap(a,b);
        add(a,b,1),add(b,a,0);
        }
        int ans=0;
        while(bfs(T))ans+=dinic(S,INF,T);
        printf("%d
    ",ans);
        return 0;
    }

    +++++++++++++++++++++++++++++++++++++++++++

    +本文作者:luyouqi233。               +

    +欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/ +

    +++++++++++++++++++++++++++++++++++++++++++

  • 相关阅读:
    C#异常小知识
    Cisco路由器配置学习-ip accounting
    Sublime Text 3预览Markdown
    什么是permit-inside功能
    锐捷双出口
    思科双出口+策略路由+NAT
    github常见操作和常见错误
    网易注册页面知识点
    java,xml等注释删除,正则表达式使用123
    简单多线程是否安全判断
  • 原文地址:https://www.cnblogs.com/luyouqi233/p/9060489.html
Copyright © 2011-2022 走看看