给你一些区间,每个区间都有些价值。取一个区间就能获得对应的价值,并且一个点不能覆盖超过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. Python PEP8 编码规范中文版

    原文链接:https://legacy.python.org/dev/peps/pep-0008/ 参考:https://blog.csdn.net/ratsniper/article/details ...

  2. laravel服务容器

    laravel框架底层解析 本文参考陈昊<Laravel框架关键技术解析>,搭建一个属于自己的简化版服务容器.其中涉及到反射.自动加载,还是需要去了解一下. laravel服务容器 建立项 ...

  3. zepto的extend

    类型判断 var class2type = {},toString = class2type.toString,$={}; //判断类型 function type(obj) { return obj ...

  4. Linux基础学习笔记2-文件管理和重定向

    本节内容 1)文件系统结构元素 2)创建和查看文件 3)复制.转移和删除文件 4)软和硬链接 5)三种I/O设备 6)把I/O重定向至文件 7)使用管道 文件系统和结构 文件系统 文件和目录被组织成一 ...

  5. linux的使用

    第一 安装ubuntu操作系统 1. ubuntu下解决中英文输入法问题 问题: ubuntu在安装了搜狗输入法后无法切换英文,即使在搜狗输入法中设置了切换按键依然无反应, 原因在于当前系统中只有一个 ...

  6. 二、Docker部署应用

    一.有关Docker的安装请参考docker官网  Docker 提供了两个版本:社区版 (CE) 和企业版 (EE). Docker 社区版 (CE) 是开发人员和小型团队开始使用 Docker 并 ...

  7. shell命令相关

    1.服务端登录退出 登录服务器 ssh kayan.sjc@xx.xx.xx.67 退出登录:logout 192.168.0.10 2.目录管理 显示目录 pwd 创建目录 mkdir resour ...

  8. onkeyup+onafterpaste 只能输入数字和小数点--转载

    JS判断只能是数字和小数点 1.文本框只能输入数字代码(小数点也不能输入)<input onkeyup="this.value=this.value.replace(/\D/g,'') ...

  9. SECCON 2014 CTF:Shuffle

    很简单的一道小题 dia看一下是ELF文件 运行之: St0CFC}4cNOeE1WOS !eoCE{ CC T2hNto 是一串乱七八糟的字符 ida看一下: 很简单的逻辑 v5和v6是随机生成的两 ...

  10. 今天开始学Pattern Recognition and Machine Learning (PRML),章节5.2-5.3,Neural Networks神经网络训练(BP算法)

    转载请注明出处:http://www.cnblogs.com/xbinworld/p/4265530.html 这一篇是整个第五章的精华了,会重点介绍一下Neural Networks的训练方法——反 ...