码迷,mamicode.com
首页 > 其他好文 > 详细

poj 3680 Intervals 费用流

时间:2015-12-30 21:51:02      阅读:212      评论:0      收藏:0      [点我收藏+]

标签:

题目链接

给一些线段, 每个线段有一个值, 并且覆盖一些点, 求每个点被覆盖次数不超过k时, 可以取得的最大值。

首先将点离散化, 然后连边, i向i+1连一条容量为k, 费用为0的边。 对于每条线段, 起点向终点连一条容量为1, 费用为-val的边, 然后跑费用流就好。

  1 #include <iostream>
  2 #include <vector>
  3 #include <cstdio>
  4 #include <cstring>
  5 #include <algorithm>
  6 #include <cmath>
  7 #include <map>
  8 #include <set>
  9 #include <string>
 10 #include <queue>
 11 #include <stack>
 12 #include <bitset>
 13 using namespace std;
 14 #define pb(x) push_back(x)
 15 #define ll long long
 16 #define mk(x, y) make_pair(x, y)
 17 #define lson l, m, rt<<1
 18 #define mem(a) memset(a, 0, sizeof(a))
 19 #define rson m+1, r, rt<<1|1
 20 #define mem1(a) memset(a, -1, sizeof(a))
 21 #define mem2(a) memset(a, 0x3f, sizeof(a))
 22 #define rep(i, n, a) for(int i = a; i<n; i++)
 23 #define fi first
 24 #define se second
 25 typedef pair<int, int> pll;
 26 const double PI = acos(-1.0);
 27 const double eps = 1e-8;
 28 const int mod = 1e9+7;
 29 const int inf = 1061109567;
 30 const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
 31 const int maxn = 2e5+5;
 32 int num, head[maxn*2], s, t, n, k, nn, dis[maxn], flow, cost, cnt, cap[maxn], q[maxn], cur[maxn], vis[maxn];
 33 struct node
 34 {
 35     int to, nextt, c, w;
 36     node(){}
 37     node(int to, int nextt, int c, int w):to(to), nextt(nextt), c(c), w(w) {}
 38 }e[maxn*2];
 39 int spfa() {
 40     int st, ed;
 41     st = ed = 0;
 42     mem2(dis);
 43     ++cnt;
 44     dis[s] = 0;
 45     cap[s] = inf;
 46     cur[s] = -1;
 47     q[ed++] = s;
 48     while(st<ed) {
 49         int u = q[st++];
 50         vis[u] = cnt-1;
 51         for(int i = head[u]; ~i; i = e[i].nextt) {
 52             int v = e[i].to, c = e[i].c, w = e[i].w;
 53             if(c && dis[v]>dis[u]+w) {
 54                 dis[v] = dis[u]+w;
 55                 cap[v] = min(c, cap[u]);
 56                 cur[v] = i;
 57                 if(vis[v] != cnt) {
 58                     vis[v] = cnt;
 59                     q[ed++] = v;
 60                 }
 61             }
 62         }
 63     }
 64     if(dis[t] == inf)
 65         return 0;
 66     cost += dis[t]*cap[t];
 67     flow += cap[t];
 68     for(int i = cur[t]; ~i; i = cur[e[i^1].to]) {
 69         e[i].c -= cap[t];
 70         e[i^1].c += cap[t];
 71     }
 72     return 1;
 73 }
 74 int mcmf() {
 75     flow = cost = 0;
 76     while(spfa())
 77         ;
 78     return cost;
 79 }
 80 void add(int u, int v, int c, int val) {
 81     e[num] = node(v, head[u], c, val); head[u] = num++;
 82     e[num] = node(u, head[v], 0, -val); head[v] = num++;
 83 }
 84 void init() {
 85     mem1(head);
 86     num = cnt = 0;
 87     mem(vis);
 88 }
 89 pair <int, pll > a[205];
 90 int b[450];
 91 int main()
 92 {
 93     ios::sync_with_stdio(0);
 94     int T, m, x, y, z;
 95     cin>>T;
 96     while(T--) {
 97         cin>>n>>m;
 98         init();
 99         int cnt = 0;
100         for(int i = 0; i<n; i++) {
101             scanf("%d%d%d", &a[i].fi, &a[i].se.fi, &a[i].se.se);
102             b[cnt++] = a[i].fi, b[cnt++] = a[i].se.fi;
103         }
104         sort(b, b+cnt);
105         cnt = unique(b, b+cnt)-b;
106         for(int i = 1; i<=cnt; i++) {
107             add(i, i+1, m, 0);
108         }
109         for(int i = 0; i<n; i++) {
110             int u = lower_bound(b, b+cnt, a[i].fi)-b+1;
111             int v = lower_bound(b, b+cnt, a[i].se.fi)-b+1;
112             add(u, v, 1, -a[i].se.se);
113         }
114         s = 0, t = cnt+1;
115         add(s, 1, m, 0);
116         add(cnt, t, m, 0);
117         int ans = -mcmf();
118         cout<<ans<<endl;
119     }
120     return 0;
121 }

 

poj 3680 Intervals 费用流

标签:

原文地址:http://www.cnblogs.com/yohaha/p/5089797.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!