给你一些区间,每个区间都有些价值。取一个区间就能获得对应的价值,并且一个点不能覆盖超过k次,问你最大的价值是多少。

我们可以把这些区间放到一维的轴上去,然后我们可以把它看成一个需要从左到右的过程,然后这个过程中保证每个点不超过k次,并且获得的价值最大。

因为一个点不超过k次,只需要控制流入的最大流量是k,就可以保证每个点的流量都不会超过k。

建图过程:

1.超源到整个区间最小的点, 流量k, 费用0。

2.整个区间内每个点(除了最后一个点)到自己的下一个点,流量inf,费用0。

3.每个区间的左端到右端,流量1,费用就是-价值。

4.整个区间的最后一个点到超汇,流量k, 费用0.

这样其实就是如果我极端情况,所有区间都经过了某一点,但是我的流量只有k,所以我不会让这个点被覆盖k次以上。

如果每个区间都流完了还有多余的流量,我就会从第2条路流下去,然后保证他不会多多余的费用出现。

#include<map>
#include<set>
#include<ctime>
#include<cmath>
#include<stack>
#include<queue>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define lowbit(x) (x & (-x)) typedef unsigned long long int ull;
typedef long long int ll;
const double pi = 4.0*atan(1.0);
const int inf = 0x3f3f3f3f;
const int maxn = ;
const int maxm = ;
const int mod = ;
using namespace std; int n, m, tol, T;
struct Node {
int u;
int v;
int w;
int val;
int next;
};
Node node[maxn];
struct Edge{
int l;
int r;
int w;
bool operator< (Edge a) const {
return l < a.l;
}
};
Edge edge[maxn];
int head[maxn];
int cap[maxn];
int dis[maxn];
int pre[maxn];
bool vis[maxn];
int a[maxn]; void init() {
tol = ;
memset(a, , sizeof a);
memset(node, , sizeof node);
memset(head, -, sizeof head);
} void addnode(int u, int v, int w, int val) {
node[tol].u = u;
node[tol].v = v;
node[tol].w = w;
node[tol].val = val;
node[tol].next = head[u];
head[u] = tol++;
} bool spfa(int src, int des, int &flow, int &cost) {
memset(pre, , sizeof pre);
memset(dis, inf, sizeof dis);
memset(cap, inf, sizeof cap);
memset(vis, false, sizeof vis);
queue<int > q;
pre[src] = src;
vis[src] = true;
dis[src] = ;
cap[src] = inf;
q.push(src);
while(!q.empty()) {
int u = q.front();
q.pop();
vis[u] = false;
for(int i=head[u]; ~i; i=node[i].next) {
int v = node[i].v;
if(node[i].w && dis[v] > dis[u] + node[i].val) {
dis[v] = dis[u] + node[i].val;
cap[v] = min(cap[u], node[i].w);
pre[v] = i;
if(!vis[v]) {
vis[v] = true;
q.push(v);
}
}
}
}
if(dis[des] == inf) return false;
flow += cap[des];
cost += cap[des] * dis[des];
int u = des;
while(u != src) {
node[pre[u]].w -= cap[des];
node[pre[u]^].w += cap[des];
u = node[pre[u]].u;
}
return true;
} int MCMF(int src, int des) {
int flow = ;
int cost = ;
while(spfa(src, des, flow, cost));
return cost;
} int main() {
scanf("%d", &T);
while(T--) {
init();
scanf("%d%d", &n, &m);
int nn = ;
for(int i=; i<=n; i++) {
scanf("%d%d%d", &edge[i].l, &edge[i].r, &edge[i].w);
a[++nn] = edge[i].l;
a[++nn] = edge[i].r;
}
sort(edge+, edge++n);
sort(a+, a++nn);
nn = unique(a+, a++nn) - (a+);
int mi = inf, ma = -inf;
for(int i=; i<=n; i++) {
edge[i].l = lower_bound(a+, a++nn, edge[i].l) - a;
mi = min(mi, edge[i].l);
ma = max(ma, edge[i].l);
edge[i].r = lower_bound(a+, a++nn, edge[i].r) - a;
mi = min(mi, edge[i].r);
ma = max(ma, edge[i].r);
}
int src = mi-;
int des = ma+;
addnode(src, mi, m, );
addnode(mi, src, , );
addnode(ma, des, m, );
addnode(des, ma, , );
for(int i=mi; i<ma; i++) {
addnode(i, i+, inf, );
addnode(i+, i, , );
}
for(int i=; i<=n; i++) {
addnode(edge[i].l, edge[i].r, , -edge[i].w);
addnode(edge[i].r, edge[i].l, , edge[i].w);
}
/*
for(int i=0; i<tol; i++) {
printf("%d %d %d %d\n", node[i].u, node[i].v, node[i].w, node[i].val);
}
*/
int ans = -MCMF(src, des);
printf("%d\n", ans);
}
return ;
}

Intervals POJ - 3680 (MCMF)的更多相关文章

  1. 【LeetCode】435. Non-overlapping Intervals 解题报告(Python)

    [LeetCode]435. Non-overlapping Intervals 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemi ...

  2. 2014湘潭全国邀请赛I题 Intervals /POJ 3680 / 在限制次数下取有权区间使权最大/小问题(费用流)

    先说POJ3680:给n个有权(权<10w)开区间(n<200),(区间最多数到10w)保证数轴上所有数最多被覆盖k次的情况下要求总权最大,输出最大权. 思路:       限制的处理:s ...

  3. POJ题目(转)

    http://www.cnblogs.com/kuangbin/archive/2011/07/29/2120667.html 初期:一.基本算法:     (1)枚举. (poj1753,poj29 ...

  4. Repeater POJ - 3768 (分形)

    Repeater POJ - 3768 Harmony is indispensible in our daily life and no one can live without it----may ...

  5. Booksort POJ - 3460 (IDA*)

    Description The Leiden University Library has millions of books. When a student wants to borrow a ce ...

  6. Radar Installation POJ - 1328(贪心)

    Assume the coasting is an infinite straight line. Land is in one side of coasting, sea in the other. ...

  7. Best Cow Fences POJ - 2018 (二分)

    Farmer John's farm consists of a long row of N (1 <= N <= 100,000)fields. Each field contains ...

  8. E - The Balance POJ - 2142 (欧几里德)

    题意:有两种砝码m1, m2和一个物体G,m1的个数x1,  m2的个数为x2, 问令x1+x2最小,并且将天平保持平衡 !输出  x1 和 x2 题解:这是欧几里德拓展的一个应用,欧几里德求不定方程 ...

  9. poj 1220(短除法)

    http://poj.org/problem?id=1220 题意:进制转换,把a进制转换为b进制. 如果数据不大的话,那么这个题还是很简单的,但这个题就是数据范围太大,所以这里可以采用短除法来做. ...

随机推荐

  1. centOS7防火墙关闭失败问题

    CentOS7命令: 查看防火墙状态:firewall-cmd --state 关闭防火墙:systemctl stop firewalld.service 禁止开机自启:systemctl disa ...

  2. RandomStringUtils

    System.out.println(RandomStringUtils.random(5));//随机多少个随机字符中文环境乱码 System.out.println(RandomStringUti ...

  3. Git使用:Linux(Ubuntu 14.04 x64)下安装Git并配置连接GitHub

    github是一个非常好的网络代码托管仓库,知晓许久,但是一直没有用起来,最近才开始使用git管理自己的文档和代码. Git是非常强大的版本管理工具,今天就告诉大家,如何在Linux下安装GIt,并且 ...

  4. select、poll、epoll之间的区别(搜狗面试)

    (1)select==>时间复杂度O(n) 它仅仅知道了,有I/O事件发生了,却并不知道是哪那几个流(可能有一个,多个,甚至全部),我们只能无差别轮询所有流,找出能读出数据,或者写入数据的流,对 ...

  5. ArcGIS中使用异步回调函数查询图层Graphic

    在我们的地图的操作中经常会有一些操作是需要通过画多边形或者画线来查找某一块区域内的特定的Graphics比如我们在做的交警的项目中通过框选来查找某一块区域中的摄像机,某一块区域中的警力.警情.警员等相 ...

  6. Lodop连续打印内容逐渐偏移怎么办

    Lodop打印控件中,可以使用打印机自带的纸张名称,也可以自定义纸张.(SET_PRINT_PAGESIZE语句).通常进行打印开发,为了避免浪费纸张,会用虚拟打印机效果作为依据,虚拟打印机连续打印多 ...

  7. 扒一扒开源世界有哪些licenses?

    摘要:license,中文译为“许可证”.在开源世界里,license是具有法律效力的,通过选择相应的license,版权拥有者可以声称自己相应的权利,包括其他人使用.修改.引用.共享等一系列涉及版权 ...

  8. react用构造函数创建组件

    有两种方法,一种是通过构造函数创建,一种是通过class创建 1.构造函数创建组件 用function+组件名的方式创建,创建好了,在render里面以标签的形式一丢就可以啦!但是这种方式必须要ret ...

  9. java 中的包概念

    Java 中的包package, 就是电脑中的文件夹.我们平时在工作中,文件太多时,都会新建文件夹进行分类管理,java 中的包也是类似的道理,当我们的类太多时,也需要进行分类管理,这时我们就会把类文 ...

  10. P2141 珠心算测验

    P2141 题目描述 珠心算是一种通过在脑中模拟算盘变化来完成快速运算的一种计算技术.珠心算训练,既能够开发智力,又能够为日常生活带来很多便利,因而在很多学校得到普及. 某学校的珠心算老师采用一种快速 ...