poj3680 Intervals
来源:互联网 发布:水性木器漆品牌 知乎 编辑:程序博客网 时间:2024/06/06 06:54
先把区间端点离散化为n个点,再添加源点s和汇点t。s向第一个点连边,容量为k,费用为0;第i个点向第i+1个点连边,容量为oo,费用为0;第n个点向t连边,容量为k,费用为0。假如某个区间端点离散成a,b,则由a向b连边,容量为1,费用为-w(w为该区间的权值)。然后对该网络求最小费用最大流~~
#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>#include <queue>#include <map>using namespace std;const int maxn = 444;const int maxm = 1500;const int oo = 1 << 30;int n, k, idx;int source, sink, vn;int dis[maxn], pre[maxn], head[maxn];bool vis[maxn];map<int, int> m;int a[maxn], b[maxn], w[maxn];struct Node{int u;int v;int cap;int cost;int next;}edge[maxm];void addEdge(int u, int v, int cap, int cost){edge[idx].u = u;edge[idx].v = v;edge[idx].cap = cap;edge[idx].cost = cost;edge[idx].next = head[u];head[u] = idx++;edge[idx].u = v;edge[idx].v = u;edge[idx].cap = 0;edge[idx].cost = -cost;edge[idx].next = head[v];head[v] = idx++;}bool spfa(int s, int t, int n){int cur, i, j;memset(vis, false, sizeof(vis));memset(pre, -1, sizeof(pre));for (i = 0; i <= n; ++i) dis[i] = oo;queue<int> Q;dis[s] = 0;vis[s] = true;Q.push(s);while (!Q.empty()){cur = Q.front();Q.pop();vis[cur] = false;for (i = head[cur]; i != -1; i = edge[i].next){j = edge[i].v;if (edge[i].cap > 0 && dis[cur] + edge[i].cost < dis[j]){dis[j] = dis[cur] + edge[i].cost;pre[j] = i;if (!vis[j]){vis[j] = true;Q.push(j);}}}}return dis[t] != oo;}int minCost(int s, int t, int n){int ret = 0, flow = oo;while (spfa(s, t, n)){int i = t;while (pre[i] != -1){flow = min(flow, edge[pre[i]].cap);i = edge[pre[i]].u;}i = t;while (pre[i] != -1){ret += edge[pre[i]].cost * flow;edge[pre[i]].cap -= flow;edge[pre[i]^1].cap += flow;i = edge[pre[i]].u;}}return ret;}int main(){ int t, cnt, p[maxn]; scanf("%d", &t); while (t--) { idx = 0; cnt = 0; memset(head, -1, sizeof(head)); scanf("%d %d", &n, &k); for (int i = 1; i <= n; ++i) { scanf("%d %d %d", &a[i], &b[i], &w[i]); p[++cnt] = a[i]; p[++cnt] = b[i]; } sort(p + 1, p + cnt + 1); int tot = 0; p[++tot] = p[1]; for (int i = 2; i <= cnt; ++i) { if (p[i] != p[tot]) p[++tot] = p[i]; } for (int i = 1; i <= tot; ++i) { m[p[i]] = i; } addEdge(0, 1, k, 0); addEdge(tot, tot + 1, k, 0); for (int i = 1; i < tot; ++i) addEdge(i, i + 1, oo, 0); for (int i = 1; i <= n; ++i) addEdge(m[a[i]], m[b[i]], 1, -w[i]); printf("%d\n", -minCost(0, tot + 1, tot + 2)); } return 0;}
- poj3680 Intervals
- poj3680 Intervals
- poj3680 Intervals
- POJ3680 Intervals
- POJ3680-Intervals
- 费用流 poj3680 Intervals
- Intervals poj3680 费用流
- POJ3680: Intervals 题解
- 解题报告 之 POJ3680 Intervals
- POJ3680 Intervals(费用流)
- poj3680:Intervals(费用流)
- POJ3680——Intervals(费用流)
- POJ3680——Intervals(费用流)
- POJ3680 Intervals (区间K覆盖问题)
- POJ3680 Intervals 离散化+最小费用流
- 【POJ3680】Intervals 最小费用最大流
- poj3680 Intervals (费用流巧妙的建图)
- poj3680 Intervals 【最小费用最大流+离散化】
- 代理类的理解
- Linux 查看系统配置
- Read-only file system:android
- FrameBuffer和android系列(二)
- java代理模式--动态代理
- poj3680 Intervals
- 软件专业学习之成长志(二)
- SQL 已更新或删除的行值要么不能使该行成为唯一行(sqlserver中有多行所有的列重复的数据,无法更新或删除问题)
- 敏捷开发一千零一问系列之十一:需求谁做主?
- 神是练出来的……
- Linux msmtp+mail邮件发送
- ffmpeg和SDL教程(二)输出到屏幕
- Linq使用1
- Ice自学第一步——Windows下安装Ice和设置Ice的环境变量