POJ3680-Intervals

来源:互联网 发布:linux mrtg定制 编辑:程序博客网 时间:2024/05/23 17:55

Intervals
Time Limit: 5000MS Memory Limit: 65536KTotal Submissions: 8363 Accepted: 3569

Description

You are given N weighted open intervals. The ith interval covers (aibi) and weighs wi. Your task is to pick some of the intervals to maximize the total weights under the limit that no point in the real axis is covered more than k times.

Input

The first line of input is the number of test case.
The first line of each test case contains two integers, N and K (1 ≤ K ≤ N ≤ 200).
The next N line each contain three integers aibiwi(1 ≤ ai < bi ≤ 100,000, 1 ≤ wi ≤ 100,000) describing the intervals. 
There is a blank line before each test case.

Output

For each test case output the maximum total weights in a separate line.

Sample Input

43 11 2 22 3 43 4 83 11 3 22 3 43 4 83 11 100000 1000001 2 3100 200 3003 21 100000 1000001 150 301100 200 300

Sample Output

1412100000100301

Source

POJ Founder Monthly Contest – 2008.07.27, windy7926778 


题意:给出n个区间及其权值,从中选出一些区间使它们的权值合最大,任意一个点最多可以被覆盖k次
解题思路:先将所有点离散化一下,把区间所有的端点从小到大编号构图:
1.连接第i和i + 1个端点,容量设置为k,权值为0
2.连接第一个端点和源点,连接最后的端点和汇点,容量为k,权值为0(这样可以使每个点覆盖不超过k次)
3.连接所有区间端点(左边的连向右边的),容量为1,权值为该区间的权值*( - 1)(一个区间只能使用一次)
跑一遍最小费用流得出答案


#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <algorithm>#include <cmath>#include <map>#include <set>#include <stack>#include <queue>#include <vector>#include <bitset>using namespace std;#define LL long longconst int INF = 0x3f3f3f3f;int vis[405],d[405],pre[405],a[405];struct Edge{    int u, v, c, cost, next;} edge[200009];int s[405], cnt;void init(){    cnt = 0;    memset(s, -1, sizeof(s));}void add(int u, int v, int c, int cost){    edge[cnt].u = u;    edge[cnt].v = v;    edge[cnt].cost = cost;    edge[cnt].c = c;    edge[cnt].next = s[u];    s[u] = cnt++;    edge[cnt].u = v;    edge[cnt].v = u;    edge[cnt].cost = -cost;    edge[cnt].c = 0;    edge[cnt].next = s[v];    s[v] = cnt++;}bool spfa(int ss, int ee,int &flow,int &cost){    queue<int> q;    memset(d, INF, sizeof d);    memset(vis, 0, sizeof vis);    d[ss] = 0, vis[ss] = 1, pre[ss] = 0, a[ss] = INF;    q.push(ss);    while (!q.empty())    {        int u = q.front();q.pop();        vis[u] = 0;        for (int i = s[u]; ~i; i = edge[i].next)        {            int v = edge[i].v;            if (edge[i].c>0&& d[v]>d[u] + edge[i].cost)            {                d[v] = d[u] + edge[i].cost;                pre[v] = i;                a[v] = min(a[u], edge[i].c);                if (!vis[v])                {                    vis[v] = 1;                    q.push(v);                }            }        }    }    if (d[ee] == INF) return 0;    flow += a[ee];    cost += d[ee]*a[ee];    int u = ee;    while (u != ss)    {        edge[pre[u]].c -= a[ee];        edge[pre[u] ^ 1].c += a[ee];        u = edge[pre[u]].u;    }    return 1;}int MCMF(int ss, int ee){    int cost = 0, flow=0;    while (spfa(ss, ee, flow, cost));    return cost;}int l[205],r[205],val[205],x[405];int main(){    int n,k,t;    scanf("%d",&t);    while (t--)    {        scanf("%d%d", &n, &k);        init();        for(int i=1;i<=n;i++)        {            scanf("%d%d%d",&l[i],&r[i],&val[i]);            x[i*2-1]=l[i],x[2*i]=r[i];        }        sort(x+1,x+2*n+1);        int m=unique(x+1,x+1+2*n)-x;        int s = 0, e = m ;        for (int i = 1; i < m-1; i++) add(i, i+1, k, 0);        add(s,1,k,0);add(m-1,e,k,0);        for(int i=1;i<=n;i++)        {            int ll=lower_bound(x+1,x+m,l[i])-x;            int rr=lower_bound(x+1,x+m,r[i])-x;            add(ll,rr,1,-val[i]);        }        printf("%d\n", -MCMF(s, e));    }    return 0;}

原创粉丝点击