• POJ2047 Concert Hall Scheduling(最小费用最大流)


    题目大概是有两个音乐厅,有n个乐队申请音乐厅,他们必须从第ii天到第ji天连续开音乐会且他们的开价是wi,每天每个音乐厅都只能供一个乐队进行音乐会。问接受哪些乐队的申请,获利最多能多少。

    这题相当于在一条数轴上选择最大权和的线段,使两两相交的线段不超过两个。POJ3680,区间k覆盖。

    先把每个申请的时间段处理成左闭右开的区间,然后离散化,建容量网络,跑MCMF即可。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<queue>
     4 #include<algorithm>
     5 using namespace std;
     6 #define INF (1<<30)
     7 #define MAXN 1111
     8 #define MAXM 1111*1111*2
     9 struct Edge{
    10     int u,v,cap,cost,next;
    11 }edge[MAXM];
    12 int vs,vt,NV,NE,head[MAXN];
    13 void addEdge(int u,int v,int cap,int cost){
    14     edge[NE].u=u; edge[NE].v=v;
    15     edge[NE].cap=cap; edge[NE].cost=cost;
    16     edge[NE].next=head[u]; head[u]=NE++;
    17     edge[NE].u=v; edge[NE].v=u;
    18     edge[NE].cap=0; edge[NE].cost=-cost;
    19     edge[NE].next=head[v]; head[v]=NE++;
    20 }
    21 int d[MAXN],pre[MAXN];
    22 bool vis[MAXN];
    23 bool SPFA(){
    24     for(int i=0; i<NV; ++i){
    25         d[i]=INF; vis[i]=0;
    26     }
    27     d[vs]=0; vis[vs]=1;
    28     queue<int> que;
    29     que.push(vs);
    30     while(!que.empty()){
    31         int u=que.front(); que.pop();
    32         for(int i=head[u]; i!=-1; i=edge[i].next){
    33             int v=edge[i].v;
    34             if(edge[i].cap && d[v]>d[u]+edge[i].cost){
    35                 d[v]=d[u]+edge[i].cost;
    36                 pre[v]=i;
    37                 if(!vis[v]){
    38                     vis[v]=1;
    39                     que.push(v);
    40                 }
    41             }
    42         }
    43         vis[u]=0;
    44     }
    45     return d[vt]!=INF;
    46 }
    47 int MCMF(){
    48     int res=0;
    49     while(SPFA()){
    50         int flow=INF,cost=0;
    51         for(int u=vt; u!=vs; u=edge[pre[u]].u){
    52             flow=min(flow,edge[pre[u]].cap);
    53         }
    54         for(int u=vt; u!=vs; u=edge[pre[u]].u){
    55             edge[pre[u]].cap-=flow;
    56             edge[pre[u]^1].cap+=flow;
    57             cost+=flow*edge[pre[u]].cost;
    58         }
    59         res+=cost;
    60     }
    61     return res;
    62 }
    63 int x[1111],y[1111],w[1111],point[2222],pn;
    64 int getposi(int a){
    65     return lower_bound(point,point+pn,a)-point;
    66 }
    67 int main(){
    68     int n;
    69     while(~scanf("%d",&n) && n){
    70         pn=0;
    71         for(int i=0; i<n; ++i){
    72             scanf("%d%d%d",x+i,y+i,w+i);
    73             point[pn++]=x[i];
    74             point[pn++]=++y[i];
    75         }
    76         sort(point,point+pn);
    77         pn=unique(point,point+pn)-point;
    78         vs=pn; vt=vs+1; NV=vt+1; NE=0;
    79         memset(head,-1,sizeof(head));
    80         addEdge(vs,0,2,0); addEdge(pn-1,vt,2,0);
    81         for(int i=1; i<pn; ++i){
    82             addEdge(i-1,i,INF,0);
    83         }
    84         for(int i=0; i<n; ++i){
    85             addEdge(getposi(x[i]),getposi(y[i]),1,-w[i]);
    86         }
    87         printf("%d
    ",-MCMF());
    88     }
    89     return 0;
    90 }
  • 相关阅读:
    HDU 6143 Killer Names【dp递推】【好题】【思维题】【阅读题】
    HDU 6143 Killer Names【dp递推】【好题】【思维题】【阅读题】
    POJ 3974 Palindrome【manacher】【模板题】【模板】
    POJ 3974 Palindrome【manacher】【模板题】【模板】
    HDU 6127 Hard challenge【计算机几何】【思维题】
    HDU 6127 Hard challenge【计算机几何】【思维题】
    HDU 6129 Just do it【杨辉三角】【思维题】【好题】
    HDU 6129 Just do it【杨辉三角】【思维题】【好题】
    HDU 3037 Saving Beans【Lucas定理】【模板题】【模板】【组合数取余】
    8.Math 对象
  • 原文地址:https://www.cnblogs.com/WABoss/p/5294399.html
Copyright © 2020-2023  润新知