zoukankan      html  css  js  c++  java
  • [bzoj1934/2768][Shoi2007]Vote 善意的投票_最小割

    Vote 善意的投票 bzoj-1934 Shoi-2007

    题目大意题目链接

    注释:略。


    想法

    这是最小割的一个比较基本的模型。

    我们将所有当前同意的小朋友连向源点,边权为1。不容易的连向汇点,边权为1。

    如果两个小朋友是好朋友那就把他们之间连一条边权为1的无向边即可。

    最后和源点联通的点表示选择了同意,和汇点联通的点表示选择不同意。

    Code

    #include <bits/stdc++.h>
    #define inf 1000000000 
    #define N 100010 
    using namespace std;
    int to[N<<3],nxt[N<<3],head[N<<3],tot=1,f[N<<3],dis[N<<3],s,t,n,m;
    inline void add(int x,int y,int z)
    {
    	to[++tot]=y; f[tot]=z; nxt[tot]=head[x]; head[x]=tot;
    	to[++tot]=x; f[tot]=0; nxt[tot]=head[y]; head[y]=tot;
    }
    bool bfs()
    {
    	queue<int>q; memset(dis,-1,sizeof dis); while(!q.empty()) q.pop();
    	q.push(s); dis[s]=0; while(!q.empty())
    	{
    		int x=q.front(); q.pop(); for(int i=head[x];i;i=nxt[i]) if(f[i]&&dis[to[i]]<0)
    		{
    			dis[to[i]]=dis[x]+1; q.push(to[i]);
    			if(to[i]==t) return true;
    		}
    	}
    	return false;
    }
    int dinic(int x,int fl)
    {
    	int tmp=fl;
    	if(x==t) return fl;
    	for(int i=head[x];i;i=nxt[i]) if(f[i]>0&&dis[to[i]]==dis[x]+1)
    	{
    		int a=dinic(to[i],min(f[i],tmp));
    		if(!a) dis[to[i]]=-1;
    		tmp-=a; f[i]-=a; f[i^1]+=a;
    		if(!tmp) break;
    	}
    	return fl-tmp;
    }
    int main()
    {
    	scanf("%d%d",&n,&m); s=n+1,t=n+2; for(int i=1;i<=n;i++)
    	{
    		int x; scanf("%d",&x);
    		if(x) add(s,i,1); else add(i,t,1);
    	}
    	for(int i=1;i<=m;i++)
    	{
    		int x,y; scanf("%d%d",&x,&y);
    		add(x,y,1); add(y,x,1);
    	}
    	int ans=0; while(bfs()) ans+=dinic(s,inf); cout << ans << endl ;
    	return 0;
    }
    

    小结:最小割。

  • 相关阅读:
    记一次CTF出题WP
    markdown测试
    高强度学习训练第二天总结:Opencv+Android+CameraView小demo
    高强度学习训练第一天总结:Java内存区域
    黑客中最受欢迎的工具排行榜
    Java面试复习(纯手打)
    深度学习概论学习笔记
    TensorFlow、numpy、matplotlib、基本操作
    OpenCV 笔记
    Vue Stomp+SocketJS 数据报错[Object object]
  • 原文地址:https://www.cnblogs.com/ShuraK/p/10239072.html
Copyright © 2011-2022 走看看