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

    最大流。。建图方式都是玄学啊。。

    //Dinic是O(n2m)的。 
    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    int read(){
        int x=0;char c=getchar();
        while(!isdigit(c)) c=getchar();
        while(isdigit(c)) x=x*10+c-'0',c=getchar();
        return x;
    }
    const int nmax=305;
    const int maxn=200000;
    const int inf=0x7f7f7f7f;
    struct edge{
        int to,cap;edge *next,*rev;
    };
    edge es[maxn],*pt=es,*head[nmax];
    void add(int u,int v,int d){
        pt->to=v;pt->cap=d;pt->next=head[u];head[u]=pt++;
        pt->to=u;pt->cap=0;pt->next=head[v];head[v]=pt++;
        head[u]->rev=head[v];head[v]->rev=head[u];
    }
    edge *cur[nmax],*p[nmax];
    int cnt[nmax],h[nmax];
    int maxflow(int s,int t,int n){
        clr(cnt,0);cnt[0]=n;clr(h,0);
        int flow=0,a=inf,x=s;edge *e;
        while(h[s]<n){
            for(e=cur[x];e;e=e->next) if(e->cap>0&&h[x]==h[e->to]+1) break;
            if(e){
                a=min(a,e->cap);p[e->to]=cur[x]=e;x=e->to;
                if(x==t){
                    while(x!=s) p[x]->cap-=a,p[x]->rev->cap+=a,x=p[x]->rev->to;
                    flow+=a;a=inf;
                }
            }else{
                if(!--cnt[h[x]]) break;
                h[x]=n;
                for(e=head[x];e;e=e->next) if(e->cap>0&&h[x]>h[e->to]+1) h[x]=h[e->to]+1,cur[x]=e;
                cnt[h[x]]++;
                if(x!=s) x=p[x]->rev->to;
            }
        }
        return flow;
    }
    int main(){
        int n=read(),m=read(),u,v,s=0,t=n+1;
        rep(i,1,n) {
            u=read();
            (!u)?add(i,t,1):add(s,i,1);
        }
        rep(i,1,m) u=read(),v=read(),add(u,v,1),add(v,u,1);
        printf("%d
    ",maxflow(s,t,t+1));
        return 0;
    }
    
    

      

    1934: [Shoi2007]Vote 善意的投票

    Time Limit: 1 Sec  Memory Limit: 64 MB
    Submit: 1888  Solved: 1169
    [Submit][Status][Discuss]

    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

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

    Source

    [Submit][Status][Discuss]
  • 相关阅读:
    【工具】使用Google搜索的一些技巧
    git merge和rebase合并分支的区别
    《人月神话》读后感
    记录 Vue 中遇见的坑
    chrome信任http
    sed命令替换配置文件
    中控考勤机IP能ping通,但是同过接口连接不上的解决版本
    如何启动解压版的Tomcat6.0
    服务器获取客户端ip
    linux 增加权限
  • 原文地址:https://www.cnblogs.com/fighting-to-the-end/p/5858165.html
Copyright © 2011-2022 走看看