POJ Intervals (最小费用最大流)
来源:互联网 发布:办公室网络安装 编辑:程序博客网 时间:2024/05/18 03:14
题目: LINK
给定 N 个带权的开区间,第 i 个区间覆盖(ai, bi),权为 wi。现在要你挑出一些区间使得总权值最大,并且满足实轴上任意一个点被覆盖不超过 K 次。(1 <= K <= N <= 200, 1 <= ai < bi <= 100,000, 1 <= wi <= 100,000)
首先要将每个区间的端点离散化,1..M,另加源 s=0,汇 t=M+1;对每个点 i (0 <= i <= M)加边(i, i+1, K, 0);
对每个区间(ai, bi)加边(ai’, bi’, 1, -wi),其中ai’, bi’分别表示 ai, bi 离散化后对应的数值
按照这个图求最小费用最大流,得到的最小费用的相反数就是要求的结果.
#include <cstdio>#include <cstring>#include <algorithm>#include <iostream>#include <string>#include <vector>#include <cmath>#include <queue>#include <map>#include <set>using namespace std; #define INF 1000000000//typedef __int64 LL; #define N 444int t, n, k , tot, hh[N], dis[N], inq[N], S, T, pre[N]; set<int> se; map<int, int> ma; struct node { int u, v, w, c, next; }edge[1000000]; struct no { int u, v, w; }ee[N]; void init() { memset(hh, -1, sizeof(hh)); tot = 0; }void add(int u, int v, int w, int c) { edge[tot].u = u; edge[tot].v = v; edge[tot].w = w; edge[tot].c = c; edge[tot].next = hh[u]; hh[u] = tot ++; }int spfa() { queue<int > Q; memset(pre, -1, sizeof(pre)); memset(inq, 0, sizeof(inq)); for(int i = 0; i <= T; i++) dis[i] = INF; // ? dis[S] = 0; inq[S] = 1; Q.push(S); while(!Q.empty()) { int u = Q.front(); Q.pop(); inq[u] = 0; for(int i = hh[u]; i != -1; i = edge[i].next) { int v = edge[i].v; if(edge[i].w && dis[v] > dis[u] + edge[i].c){ pre[v] = i; dis[v] = dis[u] + edge[i].c; if(!inq[v]) { inq[v] = 1; Q.push(v); } } } } return dis[T] != INF; }int mcml() { int flow, cost; flow = cost = 0; while(spfa()) { int tmp = INF; for(int i = pre[T]; i != -1; i = pre[edge[i].u]) tmp = min(tmp, edge[i].w); flow += tmp; cost += dis[T] * tmp; for(int i = pre[T]; i != -1; i = pre[edge[i].u] ) edge[i].w -= tmp, edge[i^1].w += tmp; } return cost; }int main() {#ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); #endif // ONLINE_JUDGE scanf("%d", &t); while(t -- ) { scanf("%d%d", &n, &k); init(); se.clear(); ma.clear(); for(int i = 1; i <= n; i++) { scanf("%d%d%d", &ee[i].u, &ee[i].v, &ee[i].w); se.insert(ee[i].u); se.insert(ee[i].v); } int id = 1; for(set<int >::iterator it = se.begin(); it != se.end(); it ++) { ma[*it] = id++; } // build map S = 0; T = id; for(int i = 0; i < T; i++) { add(i, i+1, k, 0); add(i+1, i, 0, 0); } for(int i = 1; i <= n; i++) { int id1= ma[ee[i].u]; int id2 = ma[ee[i].v]; add(id1, id2, 1, -ee[i].w); add(id2, id1, 0, ee[i].w); } // finish build. int ans = mcml(); printf("%d\n", -ans); } return 0; }
0 0
- POJ Intervals (最小费用最大流)
- poj 3680 Intervals (最小费用最大流)
- Intervals poj 3680 最小费用最大流
- POJ 3680 Intervals (最小费用最大流+离散化)
- POJ 3690 Intervals 费用流 最大变最小
- Intervals (poj 3680 离散化+最小费用最大流)
- 【POJ3680】Intervals 最小费用最大流
- POJ 3680 Intervals(最小费用流)
- POJ 3680 Intervals(最小费用流)
- poj 3680 Intervals 最大费用流
- Intervals----最小费用流
- POJ 3680 Intervals (最大费用最大流)
- poj3680 Intervals 【最小费用最大流+离散化】
- poj 3680 Intervals(最大费用流+离散化)
- POJ 3680Intervals (拆点 || 离散) && 最大费用流
- poj 2516 最小费用最大流
- poj/pku 3680(最小费用最大流)
- 【最小费用最大流】POJ 2516【unsolved】
- ArcGlobe 缓存管理
- uva270
- 如何创建为单个分区创建索引
- Android搜索关键字飞入飞出效果
- CC_11_排序与查找
- POJ Intervals (最小费用最大流)
- 创建一个带有CheckBox的TreeView
- 面向对象
- 动态刷新ListView
- 一种VS2010配置OPENCV的方法
- 图的邻接表的建立 c++
- 找数组中第二大的数字
- [LeetCode] Median of Two Sorted Arrays
- 获取(多)屏幕尺寸--C++