码迷,mamicode.com
首页 > 其他好文 > 详细

POJ No.3680 Intervals

时间:2016-06-01 23:14:28      阅读:398      评论:0      收藏:0      [点我收藏+]

标签:

2016-06-01 22:01:39

题目链接: POJ No.3680 Intervals

题目大意:

  给定N个带权区间,最多可以重复选一个点M次,求出一种选法使得所得权最大

解法:

  费用流

  建模:

    区间的端点之间按照副权流量1连接,而每个点之间需要再连0权流量无穷作为跳过用

注意的地方:

  十万个点肯定是不行的,看我unique离散化大法

  1 //Intervals (POJ No.3680)
  2 //费用流
  3 #include<stdio.h>
  4 #include<algorithm>
  5 #include<queue>
  6 using namespace std;
  7 const int maxn=410;
  8 int T,N,K;
  9 int hash[maxn];
 10 int a[maxn];
 11 int w[maxn];
 12 struct edge 
 13 {
 14     int to;
 15     int from;
 16     int cost;
 17     int flow;
 18     int next;
 19     edge(){}
 20     edge(int from,int to,int cost,int flow,int next):from(from),to(to),cost(cost),flow(flow),next(next){}
 21 };
 22 edge n[maxn*10];
 23 int cnt;
 24 int len;
 25 int now;
 26 int head[maxn];
 27 bool vis[maxn];
 28 int dist[maxn];
 29 int pre[maxn];
 30 queue <int> q;
 31 void insert(int x,int y,int z,int cost)
 32 {
 33     n[++cnt]=edge(x,y,cost,z,head[x]);
 34     head[x]=cnt;
 35     n[++cnt]=edge(y,x,-cost,0,head[y]);
 36     head[y]=cnt;
 37     return ;
 38 }
 39 void SPFA(int s,int t)
 40 {
 41     fill(dist,dist+maxn,100000);
 42     q.push(s);
 43     vis[s]=1;
 44     dist[s]=0;
 45     while(!q.empty())
 46     {
 47         now=q.front();
 48         q.pop();
 49         vis[now]=0;
 50         for(int i=head[now];i;i=n[i].next)
 51         {
 52             if(n[i].flow>0)
 53             {
 54                 if(dist[n[i].to]>dist[now]+n[i].cost)
 55                 {
 56                     dist[n[i].to]=dist[now]+n[i].cost;
 57                     pre[n[i].to]=i;
 58                     if(!vis[n[i].to])
 59                     {
 60                         vis[n[i].to]=1;
 61                         q.push(n[i].to);
 62                     }
 63                 }
 64             }
 65         }
 66     }
 67     for(int i=pre[t];i;i=pre[n[i].from])
 68     {
 69         n[i].flow--;
 70         n[i^1].flow++;
 71     }
 72     return ;
 73 }
 74 int Mincost_flow(int s,int t,int num)
 75 {
 76     int ans=0;
 77     while(num--)
 78     {
 79         SPFA(s,t);
 80         ans+=dist[t];
 81     }
 82     return -ans;
 83 }
 84 int main()
 85 {
 86     scanf("%d",&T);
 87     while(T--)
 88     {
 89         cnt=1;
 90         fill(head,head+maxn,0);
 91         scanf("%d %d",&N,&K);
 92         for(int i=1;i<=N;i++)
 93         {
 94             scanf("%d %d",&a[i*2-1],&a[i*2]);
 95             scanf("%d",&w[i]);
 96             hash[i*2-1]=a[i*2-1];
 97             hash[i*2]=a[i*2];
 98         }
 99         sort(hash+1,hash+2*N+1);
100         len=unique(hash+1,hash+2*N+1)-hash-1;
101         for(int i=1;i<=N*2;i++)
102         {
103             a[i]=lower_bound(hash+1,hash+len+1,a[i])-hash;
104             if(!(i&1))insert(a[i-1],a[i],1,-w[i/2]);
105         }
106         for(int i=1;i<len;i++)insert(i,i+1,100000,0);
107         insert(len,len+1,K,0);
108         insert(0,1,K,0);
109         printf("%d\n",Mincost_flow(0,len+1,K));
110     }
111 }

 

POJ No.3680 Intervals

标签:

原文地址:http://www.cnblogs.com/Neptune-/p/5551267.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!