• POJ3469 Dual Core CPU(最小割)


    题意:给你n个模块,每个模块在A核花费为ai,在B核跑花费为bi,然后由m个任务(ai,bi,wi),表示如果ai,bi不在同一个核上跑,额外的花费为wi,求最小的花费。

    一开始想的时候以为是费用流,但想着想着觉得,这么大的数据量绝对不可能是费用流。最后发现它是一个最小割模型。实际上就是要将网络里的模块划分成s-t两个点集,然后我们合适的构造一下边就可以使得对应的最小割就是我们的答案,构造的方法是这样的:当模块属于A集的时候,花费为ai,所以就从向t连一条ai的边,而当模块属于B集的时候,花费为bi,所以就由s连一条向bi的边。然后对于每个任务,当ai,bi不同的时候花费为mi,所以就由ai,bi连两条容量为wi的边,跑一下最大流就可以得出对应的最小花费了。代码将《挑战》上的模板化了一下,以后用起来会方便点吧~

    #pragma warning(disable:4996)
    #include<iostream>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cstdio>
    #include<vector>
    #include<cmath>
    #include<queue>
    #define ll long long
    #define maxn 23500
    #define maxe 1000000
    #define inf 1100000000
    using namespace std;
    
    struct Edge
    {
    	int u, v, cap;
    	int nxt;
    }edge[maxe];
    
    int head[maxn];
    int n, m;
    
    struct Dicnic
    {
    	int level[maxn];
    	int iter[maxn];
    	int add;
    	void init(){
    		add = 0; memset(head, -1, sizeof(head)); 
    		memset(iter, -1, sizeof(iter));
    	}
    	void insert(int u, int v, int c){
    		edge[add].u = u; edge[add].v = v; edge[add].cap = c;
    		edge[add].nxt = head[u]; head[u] = add++;
    		edge[add].u = v; edge[add].v = u; edge[add].cap = 0;
    		edge[add].nxt = head[v]; head[v] = add++;
    	}
    	void bfs(int s){
    		memset(level, -1, sizeof(level));
    		queue<int> que;
    		level[s] = 0;
    		que.push(s);
    		while (!que.empty()){
    			int v = que.front(); que.pop();
    			for (int i = head[v]; i != -1; i = edge[i].nxt){
    				Edge &e = edge[i];
    				if (e.cap > 0 && level[e.v] < 0){
    					level[e.v] = level[v] + 1;
    					que.push(e.v);
    				}
    			}
    		}
    	}
    
    	int dfs(int v, int t, int f){
    		if (v == t) return f;
    		for (int &i = iter[v]; i != -1; i = edge[i].nxt){
    			Edge &e = edge[i]; Edge &reve = edge[i ^ 1];
    			if (e.cap > 0 && level[v] < level[e.v]){
    				int d = dfs(e.v, t, min(f, e.cap));
    				if (d>0){
    					e.cap -= d; reve.cap += d;
    					return d;
    				}
    			}
    		}
    		return 0;
    	}
    
    	int max_flow(int s, int t){
    		int flow = 0;
    		for (;;){
    			bfs(s);
    			if (level[t] < 0) return flow;
    			memcpy(iter, head, sizeof(iter));
    			int f;
    			while ((f = dfs(s, t, inf))>0){
    				flow += f;
    			}
    		}
    	}
    }net;
    
    int a[maxn], b[maxn];
    
    int main()
    {
    	while (cin >> n >> m){
    		net.init();
    		int s = 0, t = n + 1;
    		for (int i = 1; i <= n; i++) {
    			scanf("%d", a + i); scanf("%d", b + i);
    			net.insert(i, t, a[i]);
    			net.insert(s, i, b[i]);
    		}
    		int ui, vi, wi;
    		for (int i = 0; i < m; i++){
    			scanf("%d%d%d", &ui, &vi, &wi);
    			net.insert(ui, vi, wi);
    			net.insert(vi, ui, wi);
    		}
    		printf("%d
    ", net.max_flow(s,t));
    	}
    	return 0;
    }
    
  • 相关阅读:
    Kubernetes+Docker+Istio 容器云实践
    SDN网络IPv6组播机制支持实时视频业务海量用户扩展
    如何运用结构化思维进行故障处理
    UAVStack JVM监控分析工具:图形化展示采集及分析监控数据
    个性化推荐产品功能的设计和B端产品的功能策划方式
    Kubernetes监控实践(2):可行监控方案之Prometheus和Sensu
    demo演示如何写一个无配置格式统一的日志
    指尖前端重构(React)技术调研分析
    学习设计模式前传
    我是码农要翻身
  • 原文地址:https://www.cnblogs.com/chanme/p/3650528.html
Copyright © 2020-2023  润新知