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

    一看数据范围题意猜测是网络流。

    于是开始建模。

    我们建立源点(S)和汇点(T),将(S)向想要睡觉的小朋友连容量为1的边,将不想睡觉的小朋友向(T),连容量为1的边,朋友之间连流量为1的双向边。

    那么我们需要使图被分为两个互不连通的集合,一个和(S)连通,表示最终投了睡觉的小朋友;另一个和(T)连通,表示最终投了不睡的小朋友。

    那么最小冲突次数就是最小割了。

    为什么呢?

    可以把一条边看成一次可能的冲突,割断了就是接受了一次冲突,让一这对朋友冲突之后,两个小朋友都可以不用考虑这个朋友关系,这个限制就不存在了,也就是边被割断了。

    code:

    #include<bits/stdc++.h>
    #define REV(x) (x&1?x+1:x-1)
    #define S 0
    #define T n+1
    using namespace std;
    struct edge{
        int t,f,nxt;
    }e[200010];
    int n,m,u,v,t,cnt,be[310],dep[310],vis[310];
    queue<int>q;
    void add(int x,int y,int f){
        e[++cnt].t=y,e[cnt].f=f,e[cnt].nxt=be[x],be[x]=cnt;
    }
    void Add(int x,int y,int f){
        add(x,y,f),add(y,x,0);
    }
    bool bfs(){
        for(int i=1;i<=T;++i)dep[i]=0;
        dep[S]=1,q.push(S);
        while(!q.empty()){
            t=q.front(),q.pop();
            for(int i=be[t];i;i=e[i].nxt)!dep[e[i].t]&&e[i].f?q.push(e[i].t),dep[e[i].t]=dep[t]+1:0;
        }
        return dep[T];
    }
    int dfs(int x,int nf){
        if(x==T)return nf;
        vis[x]=1;
        int tf,uf=0;
        for(int i=be[x];i&&nf>uf;i=e[i].nxt)!vis[e[i].t]&&dep[e[i].t]==dep[x]+1&&e[i].f?tf=dfs(e[i].t,min(e[i].f,nf-uf)),uf+=tf,e[i].f-=tf,e[REV(i)].f+=tf:0;
        return uf;
    }
    int Dinic(){
        int ans=0;
        while(bfs())ans+=dfs(S,1e9);
        return ans;
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;++i)scanf("%d",&t),t?Add(S,i,1):Add(i,T,1);
        for(int i=1;i<=m;++i)scanf("%d%d",&u,&v),Add(u,v,1),Add(v,u,1);
        printf("%d",Dinic());
        return 0;
    }
    
  • 相关阅读:
    post 跨域
    鼠标滚轮 控制作用滚动
    es5的特性 有多少你没用过
    javascript 定义修改属性值
    javascript 原型继承
    C# windows 服务 操作实例
    linq to xml 操作实例
    伪随机数 避免操作
    linq 分组包含时间操作
    时间转换操作
  • 原文地址:https://www.cnblogs.com/xryjr233/p/BZOJ1934.html
Copyright © 2011-2022 走看看