• 【POJ】【3680】Intervals


    网络流/费用流


      引用下题解:

    lyd:

    首先把区间端点离散化,设原来的数值i离散化后的标号是c[i]。这样离散化之后,整个数轴被分成了一段段小区间。

    1.建立S和T,从S到离散化后的第一个点连容量K,费用0的边。离散化后的最后一个点到T连容量K、费用0的边。

    2.离散化后的相邻点之间(从i到i+1)连容量为K,费用为0的边。

    3.输入的区间从离散化后的左端点到右端点连容量1、费用W的边。

      感觉好神啊……

    其实应该只要把源点到第一个点的流量限制为k应该就可以了……这个构思蛮巧妙的……限制了每个地方最多有k个流出去。

    另外,这题是最大费用最大流,所以按上面的建图方式需要改一下预处理和增广的条件,或者就是建图的时候所有的费用取负,再将最后答案取负。

      1 Source Code
      2 Problem: 3680        User: sdfzyhy
      3 Memory: 752K        Time: 563MS
      4 Language: G++        Result: Accepted
      5 
      6     Source Code
      7 
      8     //BZOJ 3680
      9     #include<cmath>
     10     #include<vector>
     11     #include<cstdio>
     12     #include<cstring>
     13     #include<cstdlib>
     14     #include<iostream>
     15     #include<algorithm>
     16     #define rep(i,n) for(int i=0;i<n;++i)
     17     #define F(i,j,n) for(int i=j;i<=n;++i)
     18     #define D(i,j,n) for(int i=j;i>=n;--i)
     19     #define pb push_back
     20     #define CC(a,b) memset(a,b,sizeof(a))
     21     using namespace std;
     22     int getint(){
     23         int v=0,sign=1; char ch=getchar();
     24         while(!isdigit(ch)) {if(ch=='-') sign=-1; ch=getchar();}
     25         while(isdigit(ch))  {v=v*10+ch-'0'; ch=getchar();}
     26         return v*sign;
     27     }
     28     const int N=510,M=100000,INF=~0u>>2;
     29     const double eps=1e-8;
     30     /*******************template********************/
     31     int n,m,k,ans,a[N],b[N],c[N],w[N];
     32     struct edge{int from,to,v,c;};
     33     struct Net{
     34         edge E[M];
     35         int head[N],next[M],cnt;
     36         void ins(int x,int y,int z,int c){
     37             E[++cnt]=(edge){x,y,z,c};
     38             next[cnt]=head[x]; head[x]=cnt;
     39         }
     40         void add(int x,int y,int z,int c){
     41             ins(x,y,z,c); ins(y,x,0,-c);
     42         }
     43         int S,T,d[N],Q[M],from[N];
     44         bool inq[N];
     45         bool spfa(){
     46             int l=0,r=-1;
     47             F(i,S,T) d[i]=INF;
     48             d[S]=0; Q[++r]=S; inq[S]=1;
     49             while(l<=r){
     50                 int x=Q[l++]; inq[x]=0;
     51                 for(int i=head[x];i;i=next[i])
     52                     if(E[i].v && d[x]+E[i].c<d[E[i].to]){
     53                         d[E[i].to]=d[x]+E[i].c;
     54                         from[E[i].to]=i;
     55                         if (!inq[E[i].to]){
     56                             Q[++r]=E[i].to;
     57                             inq[E[i].to]=1;
     58                         }
     59                     }
     60             }
     61             return d[T]!=INF;
     62         }
     63         void mcf(){
     64             int x=INF;
     65             for(int i=from[T];i;i=from[E[i].from])
     66                 x=min(x,E[i].v);
     67             for(int i=from[T];i;i=from[E[i].from]){
     68                 E[i].v-=x;
     69                 E[i^1].v+=x;
     70             }
     71             ans+=x*d[T];
     72         }
     73         void init(){
     74             n=getint(); k=getint();
     75             cnt=1; ans=0;
     76             memset(head,0,sizeof head);
     77             int x,y;
     78             F(i,1,n){
     79                 a[i]=c[(i<<1)-1]=getint();
     80                 b[i]=c[i<<1]=getint();
     81                 w[i]=getint();
     82             }
     83             sort(c+1,c+n*2+1);
     84             int num=unique(c+1,c+n*2+1)-c-1;
     85             S=0; T=num+1;
     86             F(i,0,num) add(i,i+1,k,0);
     87             F(i,1,n){
     88                 a[i]=lower_bound(c+1,c+num+1,a[i])-c;
     89                 b[i]=lower_bound(c+1,c+num+1,b[i])-c;
     90                 add(a[i],b[i],1,-w[i]);
     91             }
     92             while(spfa()) mcf();
     93             printf("%d
    ",-ans);
     94         }        
     95     }G1;
     96     int main(){
     97     #ifndef ONLINE_JUDGE
     98         freopen("input.txt","r",stdin);
     99     //    freopen("output.txt","w",stdout);
    100     #endif
    101         int T=getint();
    102         while(T--) G1.init();
    103         return 0;
    104     }
    View Code
    Intervals
    Time Limit: 5000MS   Memory Limit: 65536K
    Total Submissions: 6880   Accepted: 2859

    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 ≤ KN ≤ 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

    [Submit]   [Go Back]   [Status]   [Discuss]

  • 相关阅读:
    真正的Java学习从入门到精通
    Java学习从入门到精通(1) [转载]
    Java Learning Path(三)过程篇
    Java Learning Path(五)资源篇
    Java Learning Path(四) 方法篇
    浅析Java语言中两种异常的差别
    JDK,JRE,JVM区别与联系
    JAVA敏捷开发环境搭建
    谈谈WEB开发中的苦大难字符集问题
    java读取clob字段的几种方法
  • 原文地址:https://www.cnblogs.com/Tunix/p/4349410.html
Copyright © 2020-2023  润新知