• uva 1317 费用流


    You are appointed director of a famous concert hall, to save it from bankruptcy. The hall is very popular, and receives many requests to use its two fine rooms, but unfortunately the previous director was not very efficient, and it has been losing money for many years. The two rooms are of the same size and arrangement. Therefore, each applicant wishing to hold a concert asks for a room without specifying which. Each room can be used for only one concert per day.

    In order to make more money, you have decided to abandon the previous fixed price policy, and rather let applicants specify the price they are ready to pay. Each application shall specify a period [i, j] and an asking price w, where i and j are respectively the first and last days of the period (1$ le$i$ le$j$ le$365), and w is a positive integer in yen, indicating the amount the applicant is willing to pay to use a room for the whole period.

    You have received applications for the next year, and you should now choose the applications you will accept. Each application should be either accepted for its whole period or completely rejected. Each concert should use the same room during the whole applied period.

    Considering the dire economic situation of the concert hall, artistic quality is to be ignored, and you should just try to maximize the total income for the whole year by accepting the most profitable applications.

    Input 

    The input has multiple data sets, each starting with a line consisting of a single integer n, the number of applications in the data set. Then, it is followed by n lines, each of which represents one application with a period [i, j] and an asking price w yen in the following format.


    i j w


    A line containing a single zero indicates the end of the input.

    The maximum number of applications in a data set is one thousand, and the maximum asking price is one million yen.

    Output 

    For each data set, print a single line containing an integer, the maximum total income in yen for the data set.

    Sample Input 

    4
    1 2 10
    2 3 10
    3 3 10
    1 3 10
    6
    1 20 1000
    3 25 10000
    5 15 5000
    22 300 5500
    10 295 9000
    7 7 6000
    8
    32 251 2261
    123 281 1339
    211 235 5641
    162 217 7273
    22 139 7851
    194 198 9190
    119 274 878
    122 173 8640
    0
    

    区间K覆盖问题,书上、网上只有构造方法, 没解释:
    最小费用流。把每个点作为一个节点,然后对于权值为w的区间[u, v),加边u->v, 容量为1,费用-w。再对所有相邻点加边i->i+1,容量为k,费用为0。最后求最左点到最右点最小费用最大流即可。
    其中每个流量对应一组互不相交区间。如果数值太大,离散化(??????????)

    理解:画图

    AC代码:
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<vector>
    #include<cstdlib>
    #include<algorithm>
    #include<queue>
    #include<map>
    
    using namespace std;
    
    #define LL long long
    #define ULL unsigned long long
    #define UINT unsigned int
    #define MAX_INT 0x7fffffff
    #define MAX_LL 0x7fffffffffffffff
    #define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
    #define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
    #define INF 100000000
    #define MAXN 370
    #define MAXM 3000
    
    struct edge{
        int u, v, cap, cst, flow, nxt;
    }e[MAXM];
    int h[MAXN], cc;
    
    void add(int u, int v, int cap, int cst){
        e[cc]=(edge){u, v, cap, cst, 0, h[u]};
        h[u]=cc++;
        e[cc]=(edge){v, u, 0, -cst, 0, h[v]};
        h[v]=cc++;
    }
    
    int d[MAXN], a[MAXN], inq[MAXN];
    int p[MAXN];
    int mcmf(int s, int t, int n){
        int flow=0, mincst=0;
        while(1){
            queue<int> q;   q.push(s);
            memset(inq, 0, sizeof(inq));
            for(int i=0; i<n; i++) d[i]=INF;
            a[s]=INF;       d[s]=0;
            inq[s]=1;
            while(!q.empty()){
                int u=q.front();    q.pop();    inq[u]=0;
                for(int i=h[u]; i!=-1; i=e[i].nxt){
                    int v=e[i].v, cap=e[i].cap, ef=e[i].flow, cst=e[i].cst;
                    if(d[v]>d[u]+cst && cap>ef){
                        p[v]=i;
                        d[v]=d[u]+cst;
                        a[v]=MIN(cap-ef, a[u]);
                        if(!inq[v]) q.push(v), inq[v]=1;
                    }
                }
            }
            if(d[t]==INF) break;
            mincst+=d[t];
            flow+=a[t];
            for(int u=t; u!=s; u=e[p[u]].u){
                e[p[u]].flow+=a[t];
                e[p[u]^1].flow-=a[t];
            }
        }
        return mincst;
    }
    
    int main(){
    //    freopen("C:\Users\Administrator\Desktop\in.txt","r",stdin);
        int n;
        while(scanf(" %d", &n)==1 && n){
            int i, u, v, w, minu=MAXN, maxv=-1;
            memset(h, -1, sizeof(h));       cc=0;
            for(i=0; i<n; i++){
                scanf(" %d %d %d", &u, &v, &w);     v++;
                minu=MIN(u, minu);
                maxv=MAX(v, maxv);
                add(u, v, 1, -w);
            }
            for(i=minu; i<maxv; i++)
                add(i, i+1, 2, 0);
            add(minu-1, minu, 2, 0);
            printf("%d
    ", -mcmf(minu-1, maxv, maxv+1));
        }
        return 0;
    }
    
  • 相关阅读:
    hdu3746Cyclic Nacklace(KMP)
    hdu2087剪花布条(KMP)
    cellspacing cellpadding
    3行3列表格 table实现,div+css实现
    自动办公系统
    (转载)互联网协议入门(二)
    (转载)互联网协议入门(一)
    去掉考勤
    第二次装OA系统
    Windows 7系统下局域网文件共享设置方法
  • 原文地址:https://www.cnblogs.com/ramanujan/p/3351174.html
Copyright © 2020-2023  润新知