您的位置:首页 > 其它

Intervals (poj 3680 离散化+最小费用最大流)

2015-09-11 17:27 471 查看
Language:
Default

Intervals

Time Limit: 5000MSMemory Limit: 65536K
Total Submissions: 7046Accepted: 2935
Description

You are given N weighted open intervals. The ith interval covers (ai, bi) 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 ai, bi, wi(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
4

3 1
1 2 2
2 3 4
3 4 8

3 1
1 3 2
2 3 4
3 4 8

3 1
1 100000 100000
1 2 3
100 200 300

3 2
1 100000 100000
1 150 301
100 200 300

Sample Output
14
12
100000
100301

Source

POJ Founder Monthly Contest – 2008.07.27, windy7926778

题意:有N个整数区间,每个区间有一个权值,从中取一些区间,使得任意整数点的重叠数不大于K,并且这些区间的总权值最大。

思路:首先区间比较大,线段比较少,考虑到离散化操作。建图比较巧妙,S->1,1->2,2->3......T-1->T这样连边,容量为k,费用为0,然后对于每条线段u->v连边,费用为-w,容量为1.
代码:

#include <iostream>
#include <functional>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#pragma comment (linker,"/STACK:102400000,102400000")
#define pi acos(-1.0)
#define eps 1e-6
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define FRE(i,a,b)  for(i = a; i <= b; i++)
#define FREE(i,a,b) for(i = a; i >= b; i--)
#define FRL(i,a,b)  for(i = a; i < b; i++)
#define FRLL(i,a,b) for(i = a; i > b; i--)
#define mem(t, v)   memset ((t) , v, sizeof(t))
#define sf(n)       scanf("%d", &n)
#define sff(a,b)    scanf("%d %d", &a, &b)
#define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
#define pf          printf
#define DBG         pf("Hi\n")
typedef long long ll;
using namespace std;

#define INF 0x3f3f3f3f
#define mod 1000000009
const int maxn = 205;
const int MAXN = 505;
const int MAXM = 200010;

struct line
{
    int a,b,w;
}line[maxn];

struct Edge
{
    int to,next,cap,flow,cost;
}edge[MAXM];

int head[MAXN],tol;
int pre[MAXN],dis[MAXN];
bool vis[MAXN];
int N,n,k;

void init(int n)
{
    N=n;
    tol=0;
    memset(head,-1,sizeof(head));
}

void addedge(int u,int v,int cap,int cost)
{
    edge[tol].to=v;
    edge[tol].cap=cap;
    edge[tol].cost=cost;
    edge[tol].flow=0;
    edge[tol].next=head[u];
    head[u]=tol++;
    edge[tol].to=u;
    edge[tol].cap=0;
    edge[tol].cost=-cost;
    edge[tol].flow=0;
    edge[tol].next=head[v];
    head[v]=tol++;
}

bool spfa(int s,int t)
{
    queue<int>q;
    for (int i=0;i<N;i++)
    {
        dis[i]=INF;
        vis[i]=false;
        pre[i]=-1;
    }
    dis[s]=0;
    vis[s]=true;
    q.push(s);
    while (!q.empty())
    {
        int u=q.front();
        q.pop();
        vis[u]=false;
        for (int i=head[u];i!=-1;i=edge[i].next)
        {
            int v=edge[i].to;
            if (edge[i].cap > edge[i].flow && dis[v] > dis[u] + edge[i].cost)
            {
                dis[v]=dis[u] + edge[i].cost;
                pre[v]=i;
                if (!vis[v])
                {
                    vis[v]=true;
                    q.push(v);
                }
            }
        }
    }
    if (pre[t]==-1) return false;
    else return true;
}

//返回的是最大流,cost存的是最小费用
int minCostMaxflow(int s,int t,int &cost)
{
    int flow=0;
    cost=0;
    while (spfa(s,t))
    {
        int Min=INF;
        for (int i=pre[t];i!=-1;i=pre[edge[i^1].to])
        {
            if (Min > edge[i].cap-edge[i].flow)
                Min=edge[i].cap-edge[i].flow;
        }
        for (int i=pre[t];i!=-1;i=pre[edge[i^1].to])
        {
            edge[i].flow+=Min;
            edge[i^1].flow-=Min;
            cost+=edge[i].cost*Min;
        }
        flow+=Min;
    }
    return flow;
}

int a[500];

int main()
{
#ifndef ONLINE_JUDGE
    freopen("C:/Users/lyf/Desktop/IN.txt","r",stdin);
#endif
    int i,j,t,u,v;
    scanf("%d",&t);
    while (t--)
    {
        scanf("%d%d",&n,&k);
        int cnt=0;
        for (i=1;i<=n;i++)
        {
            scanf("%d%d%d",&line[i].a,&line[i].b,&line[i].w);
            a[++cnt]=line[i].a;
            a[++cnt]=line[i].b;
        }
        sort(a+1,a+1+cnt);
        cnt=unique(a+1,a+1+cnt)-a-1;
        int S=0,T=cnt+1;
        init(T+1);
        addedge(S,1,k,0);
        for (i=1;i<=cnt;i++)
            addedge(i,i+1,k,0);
        for (i=1;i<=n;i++)
        {
            u=lower_bound(a+1,a+1+cnt,line[i].a)-a;
            v=lower_bound(a+1,a+1+cnt,line[i].b)-a;
            addedge(u,v,1,-line[i].w);
        }
        int ans,cost;
        ans=minCostMaxflow(S,T,cost);
        printf("%d\n",-cost);
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: