zoukankan      html  css  js  c++  java
  • POJ1149 PIGS

    gate

    用时:debug时间90分钟。

    先读m再读n

    我是傻逼(1/1)

    题目大意:
    (m)个房子,(n)个顾客。第(i)个房子里有(a_i)只猪;第(i)个顾客可以买至多(b_i)只猪,且可以打开房子(c_1,c_2,...c_j),这些同时被打开的房子中,剩余的猪的可以互相转移。求最多卖出的猪数量。

    很难想到是网络流,知道是网络流也很难建图。
    网络流建模汇总 - Edelweiss里有对这道题很详细的解释。

    • 首先设置超级源点(S)和超级汇点(T)

    设当前顾客为(i),打开的一个房子为(x),起始时猪的数量为(a_x)

    • 顾客(i)(T)连边,权值为(i)的购买上限;
    • 如果(x)第一次被打开,(S)(i)连边,权值为(a_x)
    • 如果(x)不是第一次被打开,上一个打开(x)的顾客(last[x])(i)连边,权值为(INF)
      即,(last[x])购买后剩余的猪的数量都可以转移给(i)

    (code)

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<cstring>
    #include<queue>
    #define MogeKo qwq
    using namespace std;
    
    const int maxn = 2e5+10;
    const int INF  = 0x3f3f3f3f;
    
    int n,m,k,s,t,cnt,ans;
    int head[maxn],to[maxn],nxt[maxn],w[maxn];
    int cur[maxn],dis[maxn],last[maxn],a[maxn];
    
    void add(int x,int y,int z) {
    	to[++cnt] = y;
    	nxt[cnt] = head[x];
    	head[x] = cnt;
    	w[cnt] = z;
    }
    
    void addedge(int x,int y,int z) {
    	add(x,y,z);
    	add(y,x,0);
    }
    
    bool bfs(){
    	memset(dis,0,sizeof(dis));
        queue <int> q;
        dis[s] = 1;
        q.push(s);
        while(!q.empty()) {
            int u = q.front();
            q.pop();
            for(int i = head[u]; i; i = nxt[i]) {
                int v = to[i];
                if(!dis[v] && w[i]) {
                    dis[v] = dis[u]+1;
                    q.push(v);
                }
            }
        }
        return dis[t];
    }
    
    int dfs(int u,int flow) {
    	if(u == t) return flow;
    	int sum = 0;
    	for(int &i = cur[u]; i; i = nxt[i]) {
    		int v = to[i];
    		if(dis[v] == dis[u]+1 && w[i]) {
    			int ff = dfs(v,min(flow,w[i]));
    			flow -= ff;
    			sum += ff;
    			w[i] -= ff;
    			w[i^1] += ff;
    			if(!flow) break;
    		}
    	}
    	if(!sum) dis[u] = -1;
    	return sum;
    }
    
    void dinic() {
    	while(bfs()) {
    		for(int i = 0; i <= n+1; i++)
    			cur[i] = head[i];
    		ans += dfs(s,INF);
    	}
    }
    
    int main() {
    	scanf("%d%d",&m,&n);
    	for(int i = 1; i <= m; i++)
    		scanf("%d",&a[i]);
    	s = 0,t = n+1,cnt = 1;
    	for(int i = 1; i <= n; i++) {
    		int x,y = 0;
    		scanf("%d",&k);
    		while(k--) {
    			scanf("%d",&x);
    			if(!last[x]) y += a[x];
    			else addedge(last[x],i,INF);
    			last[x] = i;
    		}
    		addedge(s,i,y);
    		scanf("%d",&y);
    		addedge(i,t,y);
    	}
    	dinic();
    	printf("%d",ans);
    	return 0;
    }
    
  • 相关阅读:
    C#构造方法重载
    coffeeScript 语法总结
    JavaScript常用代码段
    CSS选择器,CSS3选择器
    CSS实用的代码段
    Gdb 调试
    Keras同时有多个输出时损失函数计算方法和反向传播过程
    PyTorch 速查
    Keras自定义Layer使用说明
    TensorFlow Variable 和 Tensor 的区别
  • 原文地址:https://www.cnblogs.com/mogeko/p/13266094.html
Copyright © 2011-2022 走看看