选择若干条线段使权值最大,并且点覆盖次数不超过k。

建图如下:vs到0建立容量为k费用为0的边;坐标终点到vt连接一条容量为k费用为0的边;对于每两个相邻坐标连接一条容量为INF费用为0的边;对于线段每两个端点连接一条容量1费用为-cost的边。

这样跑最小费用最大流。相当于找出k个线段集合,每个集合的线段都不重合。原问题就这样求解。

 #include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
#define INF (1<<30)
#define MAXN 444
#define MAXM 444*444*2
struct Edge{
int u,v,cap,cost,next;
}edge[MAXM];
int head[MAXN];
int NV,NE,vs,vt; void addEdge(int u,int v,int cap,int cost){
edge[NE].u=u; edge[NE].v=v; edge[NE].cap=cap; edge[NE].cost=cost;
edge[NE].next=head[u]; head[u]=NE++;
edge[NE].u=v; edge[NE].v=u; edge[NE].cap=; edge[NE].cost=-cost;
edge[NE].next=head[v]; head[v]=NE++;
}
bool vis[MAXN];
int d[MAXN],pre[MAXN];
bool SPFA(){
for(int i=;i<NV;++i){
vis[i]=;
d[i]=INF;
}
vis[vs]=;
d[vs]=;
queue<int> que;
que.push(vs);
while(!que.empty()){
int u=que.front(); que.pop();
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(edge[i].cap && d[v]>d[u]+edge[i].cost){
d[v]=d[u]+edge[i].cost;
pre[v]=i;
if(!vis[v]){
vis[v]=;
que.push(v);
}
}
}
vis[u]=;
}
return d[vt]!=INF;
}
int MCMF(){
int res=;
while(SPFA()){
int flow=INF,cost=;
for(int u=vt; u!=vs; u=edge[pre[u]].u){
flow=min(flow,edge[pre[u]].cap);
}
for(int u=vt; u!=vs; u=edge[pre[u]].u){
edge[pre[u]].cap-=flow;
edge[pre[u]^].cap+=flow;
cost+=flow*edge[pre[u]].cost;
}
res+=cost;
}
return res;
} int from[],to[],cost[];
int point[],pn;
int main(){
int t,n,k;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&k);
pn=;
for(int i=; i<n; ++i){
scanf("%d%d%d",from+i,to+i,cost+i);
point[pn++]=from[i]; point[pn++]=to[i];
}
sort(point,point+pn);
pn=unique(point,point+pn)-point; vs=pn; vt=vs+; NV=vt+; NE=;
memset(head,-,sizeof(head)); addEdge(vs,,k,);
addEdge(pn-,vt,k,);
for(int i=; i<pn; ++i){
addEdge(i-,i,INF,);
}
for(int i=; i<n; ++i){
int x=lower_bound(point,point+pn,from[i])-point;
int y=lower_bound(point,point+pn,to[i])-point;
addEdge(x,y,,-cost[i]);
} printf("%d\n",-MCMF());
}
return ;
}

最新文章

  1. 【poj1260】 Pearls
  2. vim - Simple commands to remove unwanted whitespace
  3. SharePoint 2013 开发——SharePoint APP介绍
  4. CF-599B - Spongebob and Joke
  5. Swift Strings and Characters
  6. 感觉挺有意思的SQL题目
  7. 半透明边框与background-clip
  8. AngularJS1.X学习笔记11-服务
  9. nginx 实现所有的子域名301跳转到另外一个域名的对应子域名
  10. UVA 11988 Beiju Text
  11. python按照文件创建日期整理文件至文件夹
  12. 用ArcMap打开MXD文件报One or more layers failed to draw错误!
  13. Java连接oracle数据库的两种常用方法
  14. Codeforces.567E.President and Roads(最短路 Dijkstra)
  15. Java 使用 jacob 将 word 文档转换为 pdf 文件
  16. HDU 3974 Assign the task(简单线段树)
  17. HDU 4620 Fruit Ninja Extreme 暴搜
  18. [javaSE] GUI(jar包双击运行)
  19. 如何彻底修改eclipse中的名称
  20. 三十三 StringIO和BytesIO

热门文章

  1. nodejs链接mongodb数据库
  2. XPath的基本使用
  3. 图文转换——NABCD
  4. java 学习笔记——网络(Socket)
  5. postgres与osm初步使用
  6. tar 打包文件 除某个文件夹
  7. ASP.NET MVC Json()处理大数据异常解决方法,字符串的长度超过了为 maxJsonLength
  8. Linux 标准目录结构
  9. 几年前做家教写的C教程(之三专讲了递归和斐波那契)
  10. 【openGL】画正弦函数图像