zoukankan      html  css  js  c++  java
  • POJ1149 PIGS

    题意

    你有(m)个猪圈,第(i)个猪圈初始有(a_i)头猪。
    依次到来(n)个顾客,每个顾客会打开几个猪圈,你可以随意调换放置这些猪圈中的猪,再卖给这个顾客(b_i)头猪。
    求最大化总卖猪数量。
    (n leq 100,m leq 1000)

    思路

    做法很多。
    考虑最大流。把猪圈和顾客都看成点。初始从源点向(i)猪圈连流量为(a_i)的边。
    重新放猪可以视为把这些猪寄存在这个顾客手中,省些力,让顾客去放置。那么新来的顾客可以直接从原猪圈买,也可以从上一个打开这个猪圈的顾客手中买(那个顾客寄存着剩余的猪),将买主与指定猪圈及上一位顾客连流量为无穷大的边(原本应该向每个打开过的连边,但其实只向上一个连即可保证尽量多的猪都能卖出,可以减少边数)
    卖猪即从顾客向汇点连流量为(b_i)边。

    #include <cstdio>
    #include <queue>
    #include <cstring>
    const int N=1000005,INF=1000000000;
    using namespace std;
    queue <int> q;
    int m,n,x,k,a[1005],to[N],last[2005],Next[N],edge,t,deep[2005],w[N],ans,s;
    void add(int x,int y,int z){
    	to[++edge]=y;
    	Next[edge]=last[x];
    	last[x]=edge;
    	w[edge]=z;
    }
    bool bfs(int s){
    	memset(deep,0,sizeof(deep));
    	q.push(s);
    	deep[s]=1;
    	while (!q.empty()){
    		int x=q.front();
    		q.pop();
    		for (int i=last[x];i;i=Next[i])
    		if (w[i] && deep[to[i]]==0){
    			q.push(to[i]);
    			deep[to[i]]=deep[x]+1;
    		}
    	}
    	if (deep[t]) return true;
    	return false;
    }
    int c(int x){
    	return x&1?x+1:x-1; 
    }
    int dfs(int x,int now){
    	if (x==t) return now;
    	for (int i=last[x];i;i=Next[i])
    		if (deep[to[i]]>deep[x] && w[i]){
    			int di=dfs(to[i],min(now,w[i]));
    			if (di){
    				w[i]-=di;
    				w[c(i)]+=di;
    				return di;
    			}
    		}
    	return 0;
    }
    int main(){
    	scanf("%d%d",&m,&n);
    	t=n+m+1,s=n+m+2;
    	for (int i=1;i<=m;i++){
    		scanf("%d",&x);
    		add(s,i,x);
    		add(i,s,0);
    	}
    	for (int i=1;i<=n;i++){
    		scanf("%d",&k);
    		for (int j=1;j<=k;j++){
    			scanf("%d",&x);
    			if (a[x]>0) add(a[x]+m,i+m,INF),add(i+m,a[x]+m,0);
    			a[x]=i;
    			add(x,i+m,INF),add(i+m,x,0);
    		}
    		scanf("%d",&x);
    		add(i+m,t,x),add(t,i+m,0);	
    	}
    	while (bfs(s))
    		while (int di=dfs(s,INF)) ans+=di;
    	printf("%d",ans);
    	return 0;
    } 
    
    * 生而自由 爱而无畏 *
  • 相关阅读:
    LeetCode 150:逆波兰表达式求值 Evaluate Reverse Polish Notation
    LeetCode 20:有效的括号 Valid Parentheses
    LeetCode 155:最小栈 Min Stack
    rsync & sersync 实时同步
    rsync & inotify-tools 实时同步
    rsync 应用总结
    Linux 变量详解
    特殊权限
    Linux 三剑客之sed命令总结
    expect 分发ssh key脚本
  • 原文地址:https://www.cnblogs.com/flyfeather6/p/11155096.html
Copyright © 2011-2022 走看看