【题目链接】 http://poj.org/problem?id=3680

【题目大意】

  有N个带权重的区间,现在要从中选取一些区间,
  要求任意点都不被超过K个区间所覆盖,请最大化总的区间权重。

【题解】

  我们将权重取负后进行建图,对于每个区间从首到末连边,
  如果该路被增广则说明这个区间被选定,我们只要给定K的流量
  最后求出最大流下的最小费用即可

【代码】

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
const int INF=0x3f3f3f3f;
struct edge{int to,cap,cost,rev;};
const int MAX_V=10000;
int V,dist[MAX_V],prevv[MAX_V],preve[MAX_V];
vector<edge> G[MAX_V];
void add_edge(int from,int to,int cap,int cost){
G[from].push_back((edge){to,cap,cost,G[to].size()});
G[to].push_back((edge){from,0,-cost,G[from].size()-1});
}
int min_cost_flow(int s,int t,int f){
int res=0;
while(f>0){
fill(dist,dist+V,INF);
dist[s]=0;
bool update=1;
while(update){
update=0;
for(int v=0;v<V;v++){
if(dist[v]==INF)continue;
for(int i=0;i<G[v].size();i++){
edge &e=G[v][i];
if(e.cap>0&&dist[e.to]>dist[v]+e.cost){
dist[e.to]=dist[v]+e.cost;
prevv[e.to]=v;
preve[e.to]=i;
update=1;
}
}
}
}
if(dist[t]==INF)return -1;
int d=f;
for(int v=t;v!=s;v=prevv[v]){
d=min(d,G[prevv[v]][preve[v]].cap);
}f-=d;
res+=d*dist[t];
for(int v=t;v!=s;v=prevv[v]){
edge &e=G[prevv[v]][preve[v]];
e.cap-=d;
G[v][e.rev].cap+=d;
}
}return res;
}
const int MAX_N=200;
int N,K;
int a[MAX_N],b[MAX_N],w[MAX_N];
void solve(){
vector<int> x;
for(int i=0;i<N;i++){
x.push_back(a[i]);
x.push_back(b[i]);
}sort(x.begin(),x.end());
x.erase(unique(x.begin(),x.end()),x.end());
int m=x.size();
int s=m,t=s+1;
V=t+1;
for(int i=0;i<=V;i++)G[i].clear();
add_edge(s,0,K,0);
add_edge(m-1,t,K,0);
for(int i=0;i+1<m;i++)add_edge(i,i+1,INF,0);
for(int i=0;i<N;i++){
int u=find(x.begin(),x.end(),a[i])-x.begin();
int v=find(x.begin(),x.end(),b[i])-x.begin();
add_edge(u,v,1,-w[i]);
}printf("%d\n",-min_cost_flow(s,t,K));
}
void init(){
scanf("%d%d",&N,&K);
for(int i=0;i<N;i++){
scanf("%d%d%d",&a[i],&b[i],&w[i]);
}
}
int T;
int main(){
scanf("%d",&T);
while(T--){
init();
solve();
}return 0;
}

【建图优化】

void solve(){
vector<int> x;
for(int i=0;i<N;i++){
x.push_back(a[i]);
x.push_back(b[i]);
}sort(x.begin(),x.end());
x.erase(unique(x.begin(),x.end()),x.end());
int m=x.size();
int s=m,t=s+1;
V=t+1;
for(int i=0;i<=V;i++)G[i].clear();
int res=0;
add_edge(s,0,K,0);
add_edge(m-1,t,K,0);
for(int i=0;i+1<m;i++)add_edge(i,i+1,INF,0);
for(int i=0;i<N;i++){
int u=find(x.begin(),x.end(),a[i])-x.begin();
int v=find(x.begin(),x.end(),b[i])-x.begin();
add_edge(v,u,1,w[i]);
add_edge(s,v,1,0);
add_edge(u,t,1,0);
res-=w[i];
}res+=min_cost_flow(s,t,K+N);
printf("%d\n",-res);
}

最新文章

  1. 操作DOM
  2. tar 解压常用压缩文件格式命令大全
  3. LuaXMLRPC笔记
  4. JavaScript表单提交四种方式
  5. NameValueCollection详解
  6. lisener在web.xml中设置
  7. 转:NoSQL更适合担当云数据库吗
  8. d039: 点的位置
  9. sudo gedit xx warning
  10. (数字IC)低功耗设计入门(四)——RTL级低功耗设计
  11. Sql 关于 查俩个表 第二个表用到第一个表的某一个数据
  12. Good Introduction of Kerberos and RADIUS
  13. 用java输入分数,得出分数等级
  14. phpstudy添加redis扩展
  15. You Don&#39;t Know JS: Scope &amp; Closures (第一章:什么是Scope)
  16. WeakReference 学习和使用
  17. [django实践]投票app
  18. 用Jq遍历一个div里面的所有input 并判断是否为空?
  19. 第二百六十七节,Tornado框架-分页封装模块
  20. dede标签:arclist标签使用大全

热门文章

  1. hnust 好友互动标识
  2. HDU 4681 String 胡搞
  3. 爬虫python
  4. vmware中linux虚拟机使用NAT模式不能连接外网解决
  5. asp.net 存储过程 输出参数 取不到值
  6. linux shell常用语法
  7. 【CF Round 439 E. The Untended Antiquity】
  8. input输入限制(持续更新)
  9. [原]C++拾遗
  10. shell面试经典70例