zoukankan      html  css  js  c++  java
  • POJ3680 Intervals —— 区间k覆盖问题(最小费用流)

    题目链接:https://vjudge.net/problem/POJ-3680

    Intervals
    Time Limit: 5000MS   Memory Limit: 65536K
    Total Submissions: 8711   Accepted: 3726

    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

    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

    题意:

    数轴上有一些带权的区间, 选出权值和尽量大的一些区间, 使得任意一个数最多被k个区间覆盖。

    题解:

    可用最小费用流解决,构图方法如下:

    1.把数轴上每个数作为一个点。

    2.对于相邻的点,连一条边:i-->i+1, 容量为k, 费用为0。i-->i+1设为k,保证了x-->i(0<=x<i)的流量不高于k。因此,还需在数轴的最右边增加一个汇点, 数轴的最后一个点连向此汇点,容量为k, 费用为0。

    3.对于区间[u, v], 连一条边:u-->v,容量为1, 费用为-w。

    4.以数轴最左端的点作为源点,跑最小费用流, 把得到的最小花费取反,即为答案。

    5.由于此题数轴的范围比较大,而实际用到的点却很少,所以可以先对数轴进行离散化。

    代码如下:

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 #include <vector>
      6 #include <cmath>
      7 #include <queue>
      8 #include <stack>
      9 #include <map>
     10 #include <string>
     11 #include <set>
     12 using namespace std;
     13 typedef long long LL;
     14 const int INF = 2e9;
     15 const LL LNF = 9e18;
     16 const int mod = 1e9+7;
     17 const int MAXM = 1e5+10;
     18 const int MAXN = 400+10;
     19 
     20 struct Edge
     21 {
     22     int to, next, cap, flow, cost;
     23 }edge[MAXM];
     24 int tot, head[MAXN];
     25 int pre[MAXN], dis[MAXN];
     26 bool vis[MAXN];
     27 int N;
     28 
     29 void init(int n)
     30 {
     31     N = n;
     32     tot = 0;
     33     memset(head, -1, sizeof(head));
     34 }
     35 
     36 void add(int u, int v, int cap, int cost)
     37 {
     38     edge[tot].to = v;  edge[tot].cap = cap;  edge[tot].cost = cost;
     39     edge[tot].flow = 0;   edge[tot].next = head[u];   head[u] = tot++;
     40     edge[tot].to = u;   edge[tot].cap = 0;  edge[tot].cost = -cost;
     41     edge[tot].flow = 0; edge[tot].next = head[v];   head[v] = tot++;
     42 }
     43 
     44 bool spfa(int s, int t)
     45 {
     46     queue<int>q;
     47     for(int i = 0; i<N; i++)
     48     {
     49         dis[i] = INF;
     50         vis[i] = false;
     51         pre[i] = -1;
     52     }
     53 
     54     dis[s] = 0;
     55     vis[s] = true;
     56     q.push(s);
     57     while(!q.empty())
     58     {
     59         int u  = q.front();
     60         q.pop();
     61         vis[u] = false;
     62         for(int i = head[u]; i!=-1; i = edge[i].next)
     63         {
     64             int v = edge[i].to;
     65             if(edge[i].cap>edge[i].flow && dis[v]>dis[u]+edge[i].cost)
     66             {
     67                 dis[v] = dis[u]+edge[i].cost;
     68                 pre[v] = i;
     69                 if(!vis[v])
     70                 {
     71                     vis[v] = true;
     72                     q.push(v);
     73                 }
     74             }
     75         }
     76     }
     77     if(pre[t]==-1) return false;
     78     return true;
     79 }
     80 
     81 int minCostMaxFlow(int s, int t, int &cost)
     82 {
     83     int flow = 0;
     84     cost = 0;
     85     while(spfa(s,t))
     86     {
     87         int Min = INF;
     88         for(int i = pre[t]; i!=-1; i = pre[edge[i^1].to])
     89         {
     90             if(Min>edge[i].cap-edge[i].flow)
     91                 Min = edge[i].cap-edge[i].flow;
     92         }
     93         for(int i = pre[t]; i!=-1; i = pre[edge[i^1].to])
     94         {
     95             edge[i].flow += Min;
     96             edge[i^1].flow -= Min;
     97             cost += edge[i].cost*Min;
     98         }
     99         flow += Min;
    100     }
    101     return flow;
    102 }
    103 
    104 int interval[220][3];
    105 int M[MAXN];
    106 int main()
    107 {
    108     int T, n, k;
    109     scanf("%d", &T);
    110     while(T--)
    111     {
    112         scanf("%d%d", &n, &k);
    113         int cnt = 0;
    114         for(int i = 1; i<=n; i++)
    115         {
    116             scanf("%d%d%d", &interval[i][0],&interval[i][1],&interval[i][2]);
    117             M[cnt++] = interval[i][0];
    118             M[cnt++] = interval[i][1];
    119         }
    120         M[cnt++] = INF;
    121         sort(M, M+cnt);
    122         cnt = unique(M, M+cnt)-M;
    123 
    124         init(cnt);
    125         for(int i = 0; i<cnt-1; i++)
    126         {
    127             add(i, i+1, k, 0);
    128         }
    129         for(int i = 1; i<=n; i++)
    130         {
    131             int left = lower_bound(M, M+cnt, interval[i][0])-M;
    132             int right = lower_bound(M, M+cnt, interval[i][1])-M;
    133             add(left, right, 1, -interval[i][2]);
    134         }
    135 
    136         int min_cost;
    137         int start = 0, end = cnt-1;
    138         minCostMaxFlow(start, end, min_cost);
    139         printf("%d
    ", -min_cost);
    140     }
    141 }
    View Code
  • 相关阅读:
    mysql服务器上的mysql这个实例中表的介绍
    mysql的innodb存储引擎和myisam存储引擎的区别
    Ubuntu配置java环境变量
    Android_adb shell am/pm使用
    tty相关内容
    Ubuntu和windows共享文件夹
    蓝牙查询网站
    Vim折叠模式设置
    ubuntu下安装jdk
    Linux下Gcc生成和使用静态库和动态库详解
  • 原文地址:https://www.cnblogs.com/DOLFAMINGO/p/8124919.html
Copyright © 2011-2022 走看看