您的位置:首页 > 其它

POJ 3680 - intervals 一类分配任务,有重叠限制的模型..最大费用最大流..

2013-09-05 11:02 549 查看
题意:

给了N个开区间..每个区间有权值..限定不能任何一个点被K个区间覆盖..问满足条件的选择区间..使得权值之和最大为多少..

题解:

将所有的点存下来排个序..也就是离散化..那么一共2n个点..记为m,令s为超级源点..e为超级汇点..做边s->1->2->3...->m-1->m->e..每条边容量为K..费用为0...再对于N个区间,其起点往终点做边..容量为1..权值为其权值的相反数..然后跑最小费用最大流..答案就是最小费用的相反数...

这类问题...提供几个参考: 算法正确性证明DC :: Home的分析从多进程动态规划到费用流的转化

Program:

#include<iostream>  
#include<algorithm>  
#include<stdio.h>  
#include<string.h>  
#include<math.h>  
#include<queue>  
#define MAXN 1005
#define MAXM 800005  
#define oo 1000000007  
#define ll long long  
using namespace std;    
struct MCMF    
{    
       struct node    
       {    
              int x,y,c,v,next;     
       }line[MAXM];    
       int Lnum,_next[MAXN],pre[MAXN],dis[MAXN],flow,cost;    
       bool inqueue[MAXN];    
       void initial(int n)    
       {    
              Lnum=-1;    
              for (int i=0;i<=n;i++) _next[i]=-1;    
       }    
       void addline(int x,int y,int c,int v)    
       {    
              line[++Lnum].next=_next[x],_next[x]=Lnum;    
              line[Lnum].x=x,line[Lnum].y=y,line[Lnum].c=c,line[Lnum].v=v;    
              line[++Lnum].next=_next[y],_next[y]=Lnum;    
              line[Lnum].x=y,line[Lnum].y=x,line[Lnum].c=0,line[Lnum].v=-v;    
       }    
       bool SPFA(int s,int e)    
       {    
              int x,k,y;    
              queue<int> Q;    
              while (!Q.empty()) Q.pop();    
              memset(dis,0x7f,sizeof(dis));    
              memset(inqueue,false,sizeof(inqueue));    
              Q.push(s);    
              dis[s]=0,pre[s]=-1;    
              while (!Q.empty())    
              {    
                      x=Q.front(),Q.pop(),inqueue[x]=false;    
                      for (k=_next[x];k!=-1;k=line[k].next)      
                         if (line[k].c)    
                         {    
                               y=line[k].y;    
                               if (dis[y]>dis[x]+line[k].v)    
                               {    
                                        dis[y]=dis[x]+line[k].v;    
                                        pre[y]=k;    
                                        if (!inqueue[y])    
                                        {    
                                                inqueue[y]=true;    
                                                Q.push(y);    
                                        }    
                               }    
                         }    
              }    
              if (dis[e]>oo) return false;    
              flow=oo,cost=0;    
              for (k=pre[e];k!=-1;k=pre[line[k].x])     
                  flow=min(flow,line[k].c),cost+=line[k].v;        
              cost*=flow;    
              for (k=pre[e];k!=-1;k=pre[line[k].x])    
                  line[k].c-=flow,line[k^1].c+=flow;      
              return true;    
       }    
       void MinCostMaxFlow(int s,int e,int &Aflow,int &Acost)    
       {    
              Aflow=0,Acost=0;    
              while (SPFA(s,e))    
              {    
                     Aflow+=flow;    
                     Acost+=cost;     
              }         
       }    
}T;  
int L[205][3],X[505];    
int Bearch(int key,int n)
{
      int l=0,r=n+1,mid;
      while (r-l>1)
      {
               mid=l+r>>1;
               if (X[mid]<key) l=mid;
                          else r=mid;
      }
      return r;
}
int main() 
{               
      int C,N,M,K,i,x,y,s,e,Af,Ac;
      scanf("%d",&C);
      while (C--)
      {  
              scanf("%d%d",&N,&K);
              M=0;
              for (i=1;i<=N;i++)
                  scanf("%d%d%d",&L[i][0],&L[i][1],&L[i][2]),X[++M]=L[i][0],X[++M]=L[i][1];
              sort(X+1,X+1+M);
              s=0,e=500,T.initial(e);
              T.addline(s,1,K,0),T.addline(M,e,K,0);
              for (i=1;i<M;i++) T.addline(i,i+1,K,0);
              for (i=1;i<=N;i++)
              {
                       x=Bearch(L[i][0],M),y=Bearch(L[i][1],M);
                       if (x>y) swap(x,y);
                       T.addline(x,y,1,-L[i][2]);
              }              
              T.MinCostMaxFlow(s,e,Af,Ac);
              printf("%d\n",-Ac);
      } 
      return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: