zoukankan      html  css  js  c++  java
  • POJ 3680 Intervals

    传说中的区间k覆盖问题。

    给定n个带权开区间,选择其中一些使得区间权值之和最大,且所有区间内任意点被覆盖不能超过k次。

    建图方法:

    1.将区间离散化,对于离散化后的区间端点所对应的点i,i+1,加边(i,i+1,k,0)

    2.对于每个区间(a,b),所对应离散化后的点(xx,yy),加边(xx,yy,-w,1),w为区间的权值

    3.由源点src连一条到一个点的边(src,1,k,0),同理,由最后一个点t连一条道汇点sink的边(t,sink,k,0)

    跑一遍最小费用了取反即为结果。

      1 #include <cstdio>
      2 #include <algorithm>
      3 #include <cstring>
      4 #include <queue>
      5 #define maxn 410
      6 #define maxm 2010
      7 #define INF 1<<30
      8 using namespace std;
      9 struct MCMF{
     10     int src,sink,e,n;
     11     int first[maxn];
     12     int cap[maxm],cost[maxm],v[maxm],next[maxm];
     13     bool flag;
     14     void init(){
     15         e = 0;
     16         memset(first,-1,sizeof(first));
     17     }
     18 
     19     void add_edge(int a,int b,int cc,int ww){
     20         //printf("add:%d to %d,cap = %d,cost = %d
    ",a,b,cc,ww);
     21         cap[e] = cc;cost[e] = ww;v[e] = b;
     22         next[e] = first[a];first[a] = e++;
     23         cap[e] = 0;cost[e] = -ww;v[e] = a;
     24         next[e] = first[b];first[b] = e++;
     25     }
     26 
     27     int d[maxn],pre[maxn],pos[maxn];
     28     bool vis[maxn];
     29 
     30     bool spfa(int s,int t){
     31         memset(pre,-1,sizeof(pre));
     32         memset(vis,0,sizeof(vis));
     33         queue<int> Q;
     34         for(int i = 0;i <= n;i++)   d[i] = INF;
     35         Q.push(s);pre[s] = s;d[s] = 0;vis[s] = 1;
     36         while(!Q.empty()){
     37             int u = Q.front();Q.pop();
     38             vis[u] = 0;
     39             for(int i = first[u];i != -1;i = next[i]){
     40                 if(cap[i] > 0 && d[u] + cost[i] < d[v[i]]){
     41                     d[v[i]] = d[u] + cost[i];
     42                     pre[v[i]] = u;pos[v[i]] = i;
     43                     if(!vis[v[i]])  vis[v[i]] = 1,Q.push(v[i]);
     44                 }
     45             }
     46         }
     47         return pre[t] != -1;
     48     }
     49 
     50     int Mincost;
     51     int Maxflow;
     52 
     53     int MinCostFlow(int s,int t,int nn){
     54         Mincost = 0,Maxflow = 0,n = nn;
     55         while(spfa(s,t)){
     56             int min_f = INF;
     57             for(int i = t;i != s;i = pre[i])
     58                 if(cap[pos[i]] < min_f) min_f = cap[pos[i]];
     59             Mincost += d[t] * min_f;
     60             Maxflow += min_f;
     61             for(int i = t;i != s;i = pre[i]){
     62                 cap[pos[i]] -= min_f;
     63                 cap[pos[i]^1] += min_f;
     64             }
     65         }
     66         return Mincost;
     67     }
     68 };
     69 MCMF g;
     70 
     71 struct Line{
     72     int a,b,w;
     73 }line[210];
     74 int x[410];
     75 
     76 int main(){
     77     int T;
     78     scanf("%d",&T);
     79     while(T--){
     80         g.init();
     81         int N,K;
     82         scanf("%d%d",&N,&K);
     83         int cnt = 0;
     84         for(int i = 0;i < N;i++){
     85             int a,b,w;
     86             scanf("%d%d%d",&a,&b,&w);
     87             x[cnt++] = a;x[cnt++] = b;
     88             line[i].a = a;line[i].b = b;line[i].w = w;
     89         }
     90         sort(x,x+cnt);
     91         int t = unique(x,x+cnt) - x;
     92         //printf("t = %d
    ",t);
     93         for(int i = 0;i < N;i++){
     94             int xx = lower_bound(x,x+t,line[i].a) - x + 1;
     95             int yy = lower_bound(x,x+t,line[i].b) - x + 1;
     96             g.add_edge(xx,yy,1,-line[i].w);
     97         }
     98         for(int i = 1;i < t;i++){
     99             g.add_edge(i,i+1,K,0);
    100         }
    101         int src = t+1,sink = src+1;
    102         g.add_edge(src,1,K,0);
    103         g.add_edge(t,sink,K,0);
    104         int ans = g.MinCostFlow(src,sink,sink);
    105         printf("%d
    ",-ans);
    106     }
    107     return 0;
    108 }
    View Code
  • 相关阅读:
    [SCOI2012]滑雪与时间胶囊
    [SCOI2012]喵星球上的点名
    SDOI2012 Round1 day2 拯救小云公主(dis)解题报告
    SDOI2012 Round1 day2 象棋(chess)解题报告
    SDOI2012 Round1 day2 集合(set)解题报告
    [Sdoi2014]数数[数位dp+AC自动机]
    [NOI2013]快餐店
    java 日期的格式化 输入/输出
    elastic search 查询语句
    elasticsearch数据迁移——elasticsearch-dump使用
  • 原文地址:https://www.cnblogs.com/zhexipinnong/p/3356862.html
Copyright © 2011-2022 走看看