pku 3680 Intervals 最小费用流 有限制的区间覆盖求最大权值和,经典题目

简明题意:
给出一些开区间(s,e)以及权值c,要求选出一些区间,使得所有点的覆盖次数小于k并且权值和最大。

解法:
对s1,e1,s2,e2..sn,en进行排序并去重,得到有序数列a1,a2,a3..ak,然后建立网络,在ai与ai+1之间连一条容量为k,费用为0的边,对于原有区间(s,e),在s',e'(s',e'指离散化后的值)之间连一条容量为1,费用为-c的边,然后建立源点,向a1连一条容量为k,费用为0的边;建立汇点,从ak向其连容量为k,费用为0的边,最后求最小费用流即可
代码:
  1# include <cstdio>
  2# include <vector>
  3# include <cstring>
  4# include <algorithm>
  5using namespace std;
  6# define N 500                     //N+2
  7# define E 10000                    //2*E
  8#define typef int                     // type of flow
  9#define typec int                     // type of cost
 10const int inff = 0xfffffff;       // max of flow
 11const int infc = 0xfffffff;       // max of cost
 12struct network
 13{
 14  int nv, ne, pnt[E], nxt[E];
 15  int vis[N], que[N], head[N], pv[N], pe[N];
 16  typef flow, cap[E]; typec cost, dis[E], d[N];
 17  void addedge(int u, int v, typef c, typec w) 
 18  {
 19      pnt[ne] =  v; cap[ne] = c;
 20      dis[ne] = +w; nxt[ne] = head[u]; head[u] = (ne++);
 21      pnt[ne] =  u; cap[ne] = 0;
 22      dis[ne] = -w; nxt[ne] = head[v]; head[v] = (ne++);
 23  }

 24  int mincost(int src, int sink) 
 25  {
 26       int i, k, f, r; typef mxf;
 27       for (flow = 0, cost = 0; ; ) 
 28       {
 29           for(i=0;i<nv;i++) pv[i]=-1,d[i] = infc;
 30           memset(vis, 0sizeof(vis));
 31           d[src] = 0; pv[src] = src; vis[src] = 1;
 32           for (f = 0, r = 1, que[0= src; r != f; ) 
 33           {
 34                i = que[f++]; vis[i] = 0;
 35                if (N == f) f = 0;
 36                for (k = head[i]; k != -1; k = nxt[k])
 37                    if(cap[k] && dis[k]+d[i] < d[pnt[k]])
 38                    {
 39                        d[pnt[k]] = dis[k] + d[i];
 40                        if (0 == vis[pnt[k]]) 
 41                        {
 42                            vis[pnt[k]] = 1;
 43                            que[r++= pnt[k];
 44                            if (N == r) r = 0;
 45                        }

 46                        pv[pnt[k]]=i; pe[pnt[k]]=k;
 47                    }
  
 48            }

 49            if (-1 == pv[sink]) break;
 50            for (k = sink, mxf = inff; k != src; k = pv[k])
 51                if (cap[pe[k]] < mxf) mxf = cap[pe[k]];
 52            flow += mxf; cost += d[sink] * mxf;
 53            for (k = sink; k != src; k = pv[k]) 
 54            {
 55                cap[pe[k]] -= mxf; cap[pe[k] ^ 1+= mxf;
 56            }

 57       }

 58       return cost;
 59    }

 60  void build(int v) 
 61  {
 62      nv = v; ne = 0;
 63      for(int i=0;i<v;i++)
 64          head[i]=-1;
 65  }

 66  void add(int x,int y,int f,int w)//x->y up=f,cost=w
 67  {
 68      addedge(x, y, f, w);
 69  }

 70}
 net;
 71int data[400][3];
 72vector<int> map;
 73int main()
 74{
 75    int test;
 76    scanf("%d",&test);
 77    while(test--)
 78    {
 79       map.clear();
 80       int n,k;
 81       scanf("%d%d",&n,&k);
 82       for(int i=0;i<n;i++)
 83       {
 84         scanf("%d%d%d",&data[i][0],&data[i][1],&data[i][2]);
 85         map.push_back(data[i][0]);
 86         map.push_back(data[i][1]);
 87       }

 88       sort(map.begin(),map.end());
 89       vector<int>::iterator end=unique(map.begin(),map.end());
 90       while(map.end()!=end) map.pop_back();
 91       net.build(map.size()+2);
 92       for(int i=0;i<map.size()+1;i++)
 93          net.add(i,i+1,k,0);
 94       for(int i=0;i<n;i++)
 95           net.add(lower_bound(map.begin(),map.end(),data[i][0])-map.begin()+1,lower_bound(map.begin(),map.end(),data[i][1])-map.begin()+1,1,-data[i][2]);
 96       printf("%d\n",-net.mincost(0,map.size()+1));      
 97    }

 98    return 0;
 99}

100

posted on 2010-11-18 00:32 yzhw 阅读(336) 评论(0)  编辑 收藏 引用 所属分类: graph


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2010年11月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

导航

统计

公告

统计系统

留言簿(1)

随笔分类(227)

文章分类(2)

OJ

最新随笔

搜索

积分与排名

最新评论

阅读排行榜