zoukankan      html  css  js  c++  java
  • [bzoj1497][NOI2006]最大获利_网络流_最小割

    最大获利 bzoj-1497

        题目大意:可以建立一个点,花费一定的代价;将已经建立的两个点之间连边,得到一定收益。有些节点之间是不允许连边的。

        注释:1<=点数<=5,000,1<=允许连边的边数<=50,000。

          想法:将每个可以相连的点之间的边在网络流里建立成一个节点,将源点连这条边的收获,向这两条边的端点分别连两条inf的边,所有的端点向源点连边权为该点代价的边。然后由最大流等于最小割,求最大流即可。

        最后,附上丑陋的代码... ...

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #define inf 0x3f3f3f3f
    using namespace std;
    int head[400010],to[400010],nxt[400010],tot=1;
    int dis[400100];
    int n,m;
    // int p[10010];
    int f[400010];
    inline void add(int x,int y,int z)
    {
    	to[++tot]=y;
    	f[tot]=z;
    	nxt[tot]=head[x];
    	head[x]=tot;
    }
    bool bfs()
    {
    	queue<int> q;
    	memset(dis,-1,sizeof dis);
    	q.push(1);dis[1]=0;
    	while(!q.empty())
    	{
    		int x=q.front();q.pop();
    		for(int i=head[x];i;i=nxt[i])
    		{
    			if(f[i]>0&&dis[to[i]]==-1)
    			{
    				dis[to[i]]=dis[x]+1;
    				q.push(to[i]);
    				if(to[i]==n+m+2) return true;
    			}
    		}
    	}
    	return false;
    }
    int dinic(int x,int flow)
    {
    	int a,temp=flow;
    	if(x==n+m+2) return flow;
    	for(int i=head[x];i;i=nxt[i])
    	{
    		if(f[i]>0&&dis[to[i]]==dis[x]+1)
    		{
    			a=dinic(to[i],min(f[i],temp));
    			if(!a) dis[to[i]]=-1;
    			temp-=a;
    			f[i]-=a;
    			f[i^1]+=a;
    			if(!temp) break;
    		}
    	}
    	return flow-temp;
    }
    int main()
    {
    	cin >> n >> m;
    	int all=n+m+2;
    	for(int a,i=1;i<=n;i++)
    	{
    		cin >> a;
    		add(1+m+i,all,a);
    		add(all,1+m+i,0);
    	}
    	int sum=0;
    	for(int a,b,c,i=1;i<=m;i++)
    	{
    		cin >> a >> b >> c;
    		sum+=c;
    		add(1,1+i,c);add(1+i,1,0);
    		add(1+i,1+m+a,inf);add(1+m+a,1+i,0);
    		add(1+i,1+m+b,inf);add(1+m+b,1+i,0);
    	}
    	int ans=0;
    	while(bfs())
    	{
    		// puts("Fuck");
    		ans+=dinic(1,inf);
    	}
    	cout << sum - ans << endl;
    	return 0;
    }
    

         小结:最小割等于最大流

  • 相关阅读:
    蓝书·目录
    CSPs-2019·爆零游记
    [原创题目]Uncomplicated Card Recreation
    珂朵莉树(ODT)
    CF407B 「Long Path」
    Manacher(马拉车)
    CSPs-2020 游记
    STM32CubeMX的使用(以点亮闪烁LED为例)
    基于STM32CubeMX的定时器设置
    STM32的中断系统和外部中断(基于STM32CubeMX开发)
  • 原文地址:https://www.cnblogs.com/ShuraK/p/8585016.html
Copyright © 2011-2022 走看看