cf 164 C 费用流

来源:互联网 发布:sql 执行存储过程 编辑:程序博客网 时间:2024/05/17 01:38

给你n个任务,k个机器,n个任务的起始时间,持续时间,完成任务的获利

每个机器可以完成任何一项任务,但是同一时刻只能完成一项任务,一旦某台机器在完成某项任务时,直到任务结束,这台机器都不能去做其他任务

最后问你当获利最大时,应该安排那些机器工作,即输出方案

具体建图方法:

新建源汇S T‘

对任务按照起始时间s按升序排序

拆点:

u 向 u'连一条边 容量为 1 费用为 -c,

u' 向 T连一条边 容量为 inf 费用为 0;

如果任务u完成后接下来最先开始的是任务v

则从u' 向 v连一条边,容量inf 费用 0.

另外,任务从前往后具有传递性,所以必须是第i个任务向第i+1个任务建边,容量为inf

最后,限制一下起始点向第一个任务的流量即可(即K)

const int maxn = 5000 ;const int maxm = 50000 ;const int inf = 1000000000 ;struct Edge{       int v , f , w , next ;       int u ;       Edge(){}       Edge(int _v , int _f , int _w , int _next):v(_v),f(_f),w(_w),next(_next){}};int  g[maxn + 10] ;Edge e[maxm + 10] ;int  source , meet ;int  id ;void  add(int u , int v  , int f , int w){      e[++id] = Edge(v , f , w , g[u]) ;      e[id].u = u ;      g[u] = id ;      e[++id] = Edge(u , 0 , -w , g[v]) ;      e[id].u = v ;      g[v] = id ;}queue<int> que ;bool in[maxn + 10] ;int  dist[maxn + 10] ;int  pv[maxn + 10] , pe[maxn + 10] ;int bfs(){     while(! que.empty()) que.pop() ;     que.push(source) ;     memset(dist , 63 , sizeof(dist)) ;     dist[source] = 0  ;     in[source] = 1 ;     while(! que.empty()){           int u = que.front() ; que.pop() ;           in[u] = 0 ;           for(int i = g[u] ; i ; i = e[i].next){                int  v = e[i].v ;                if(e[i].f > 0 && dist[u] + e[i].w < dist[v]){                      dist[v] = dist[u] + e[i].w ;                      pv[v] = u ;                      pe[v] = i ;                      if(! in[v]){                            in[v] = 1 ;  que.push(v) ;                      }                }           }     }     return  dist[meet] < inf  ;}int  augment(){     int u = meet  ;     int delta = inf ;     while(u != source){           delta = min(delta , e[pe[u]].f) ;           u = pv[u] ;     }     u = meet ;     while(u != source){           e[pe[u]].f -= delta ;           e[pe[u] ^ 1].f += delta ;           u = pv[u] ;     }     return dist[meet] * delta ;}int  mincostflow(){     int ans = 0 ;     while(bfs())  ans += augment() ;     return ans ;}void init(){     memset(g , 0 , sizeof(g)) ;     id = 1 ;}struct  Task{        int s , e , val , id ;        friend bool operator < (const Task A , const Task B){             return A.s < B.s ;        }}tk[1008] ;int   ans[1008] ;int   main(){      int n , k  , i , j , u , v ;      while(cin>>n>>k){           for(i = 1 ; i <= n ; i++){               scanf("%d%d%d" , &tk[i].s , &tk[i].e , &tk[i].val) ;               tk[i].e = tk[i].s + tk[i].e - 1 ;               tk[i].id = i ;           }           sort(tk+1 , tk+1+n) ;           init() ;           source = 0 , meet = 2*n + 1 ;           for(i = 1 ; i <= n ; i++){                 add(i , i+n , 1 , -tk[i].val) ;                 add(i+n , meet , inf , 0) ;                 for(j = i + 1 ; j <= n ; j++){                      if(tk[i].e < tk[j].s){                           add(i+n , j , inf , 0) ;                           break ;                      }                 }                 if(i < n) add(i , i+1 , inf , 0) ;           }           add(source , 1 , k , 0) ;           add(n , meet , k , 0) ;           mincostflow() ;           memset(ans , 0 , sizeof(ans)) ;           for(i = 2 ; i <= id ; i+=2){               u = e[i].u , v = e[i].v ;               if(e[i].f == 0){                   if(u != source && v != meet && u <= n)                       ans[tk[u].id] = 1 ;               }           }           for(i = 1 ; i <= n ; i++)              printf("%d " , ans[i]) ;           puts("") ;      }      return 0 ;}


0 0
原创粉丝点击