POJ 3680:Intervals(最小费用最大流)***
http://poj.org/problem?id=3680
题意:给出n个区间[Li,Ri],每个区间有一个权值wi,要使得每个点都不被超过k个区间覆盖(最多能被k个区间覆盖),如果选取了第i个区间,那么能得到wi的权值,问最终能得到的最大权值是多少。
思路:首先把区间离散化,然后考虑构图。
第一种构图方式:
将S到第一个区间结点连一条容量为k,费用为0的边,代表最多能使用k个区间。
对于每个区间[l,r],从l到r连一条容量为1,费用为-w[i]的边(因为跑的是最大的费用),这里如果这条边的流量为1,那么代表使用了这个区间,那么就加上费用。
将最后一个区间结点连一条容量为k,费用为0的边,同S。
对于每个离散化后的区间,将i和i+1连一条容量为INF,费用为0的边,如果不跑这条边,那么说明这段区间被覆盖了。
最后将答案取反就是最终答案。
画了个图帮助理解:如果跑1->3的区间的话,那么1->3的流量是1,那么主路径在[1,3]的时候流量为k-1,然后跑2->4,主路径在[2,3]的流量就变成k-2,跑到3的时候就变回k-1,跑到4又变回k,如果k=0的时候,那么就不能被覆盖了,因此恰好可以满足限制。
第二种构图方式:
是挑战上的,对于有负权边的构图。
S和T和i到i+1的连边和上图一样。
对于[u,v],S到v连一条容量为1,费用为0的边,u到T连一条容量为1,费用为0的边,v到u连一条容量为1,费用为wi的边。
这个方法还不太理解。
- #include <cstdio>
- #include <algorithm>
- #include <iostream>
- #include <cstring>
- #include <string>
- #include <cmath>
- #include <queue>
- #include <vector>
- #include <map>
- #include <set>
- #include <stack>
- using namespace std;
- #define INF 0x3f3f3f3f
- #define N 510
- typedef long long LL;
- struct Edge {
- int u, v, nxt, cap, cost;
- } edge[N*N];
- int head[N], tot, pre[N], dis[N], vis[N], a[N], b[N], w[N], S, T;
- vector<int> vec;
- void Add(int u, int v, int cap, int cost) {
- edge[tot] = (Edge) { u, v, head[u], cap, cost }; head[u] = tot++;
- edge[tot] = (Edge) { v, u, head[v], , -cost }; head[v] = tot++;
- }
- bool SPFA(int S) {
- queue<int> que;
- que.push(S);
- memset(dis, INF, sizeof(dis));
- memset(vis, , sizeof(vis));
- dis[S] = ; vis[S] = ;
- while(!que.empty()) {
- int u = que.front(); que.pop();
- vis[u] = ;
- for(int i = head[u]; ~i; i = edge[i].nxt) {
- int v = edge[i].v, cost = edge[i].cost, cap = edge[i].cap;
- if(dis[v] > dis[u] + cost && cap > ) {
- dis[v] = dis[u] + cost;
- pre[v] = i;
- if(!vis[v]) vis[v] = , que.push(v);
- }
- }
- }
- return dis[T] < INF;
- }
- int MFMC(int S, int T) {
- int ans = , u, flow;
- while(SPFA(S)) {
- flow = INF, u = T;
- while(u != S) {
- if(flow > edge[pre[u]].cap) flow = edge[pre[u]].cap;
- u = edge[pre[u]].u;
- } u = T;
- while(u != S) {
- edge[pre[u]].cap -= flow; edge[pre[u]^].cap += flow;
- ans += flow * edge[pre[u]].cost;
- u = edge[pre[u]].u;
- }
- }
- return ans;
- }
- int main() {
- int n, k, t; scanf("%d", &t);
- while(t--) {
- scanf("%d%d", &n, &k);
- memset(head, -, sizeof(head)); tot = ;
- vec.clear();
- for(int i = ; i <= n; i++)
- scanf("%d%d%d", &a[i], &b[i], &w[i]), vec.push_back(a[i]), vec.push_back(b[i]);
- sort(vec.begin(), vec.end());
- vec.erase(unique(vec.begin(), vec.end()), vec.end()); // 新的离散化姿势
- int cnt = vec.size();
- S = , T = cnt + ;
- int ans = ;
- // First
- Add(S, , k, ); Add(cnt, T, k, );
- for(int i = ; i < cnt; i++) Add(i, i + , INF, );
- for(int i = ; i <= n; i++) {
- int u = lower_bound(vec.begin(), vec.end(), a[i]) - vec.begin() + ;
- int v = lower_bound(vec.begin(), vec.end(), b[i]) - vec.begin() + ;
- Add(u, v, , -w[i]);
- }
- ans -= MFMC(S, T);
- // Second
- // Add(S, 1, k, 0); Add(cnt, T, k, 0);
- // for(int i = 1; i < cnt; i++) Add(i, i + 1, INF, 0);
- // for(int i = 1; i <= n; i++) {
- // int u = lower_bound(vec.begin(), vec.end(), a[i]) - vec.begin() + 1;
- // int v = lower_bound(vec.begin(), vec.end(), b[i]) - vec.begin() + 1;
- // Add(S, v, 1, 0); Add(u, T, 1, 0);
- // Add(v, u, 1, w[i]);
- // ans += w[i];
- // }
- // ans -= MFMC(S, T);
- printf("%d\n", ans);
- }
- return ;
- }
- /*
- 3 1
- 1 2 2
- 2 3 4
- 3 4 8
- 3 1
- 1 3 2
- 2 3 4
- 3 4 8
- 3 2
- 1 100000 100000
- 1 150 301
- 100 200 300
- */
POJ 3680:Intervals(最小费用最大流)***的更多相关文章
- POJ 3680 Intervals 最小费用最大流(MCMF算法)
题意:给出 n ,k 表示接下来给你 n 段开区间,每段区间都有它的权值,问选出一些区间,使它的权值最大,并且在实轴上的每个点,不得超过 k次被覆盖. 思路:首先要理解建图思路,首先有一个基图,相邻点 ...
- POJ 3680 Intervals(费用流)
Intervals Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 5762 Accepted: 2288 Descrip ...
- POJ 3680 Intervals(费用流+负权优化)
[题目链接] http://poj.org/problem?id=3680 [题目大意] 有N个带权重的区间,现在要从中选取一些区间, 要求任意点都不被超过K个区间所覆盖,请最大化总的区间权重. [题 ...
- Going Home POJ - 2195 (最小费用最大流)
On a grid map there are n little men and n houses. In each unit time, every little man can move one ...
- poj 3680 Intervals(费用流)
http://poj.org/problem?id=3680 巧妙的构图. 题目:给定N个区间(ai,bi)权值wi,求最大权和且每个点最多覆盖K次. 构图:将区间端点离散化,将第i个点连第i+1个点 ...
- poj3680 Intervals 区间k覆盖问题 最小费用最大流 建图巧妙
/** 题目:poj3680 Intervals 区间k覆盖问题 最小费用最大流 建图巧妙 链接:http://poj.org/problem?id=3680 题意:给定n个区间,每个区间(ai,bi ...
- POJ 2195:Going Home(最小费用最大流)
http://poj.org/problem?id=2195 题意:有一个地图里面有N个人和N个家,每走一格的花费是1,问让这N个人分别到这N个家的最小花费是多少. 思路:通过这个题目学了最小费用最大 ...
- poj 2195 二分图带权匹配+最小费用最大流
题意:有一个矩阵,某些格有人,某些格有房子,每个人可以上下左右移动,问给每个人进一个房子,所有人需要走的距离之和最小是多少. 貌似以前见过很多这样类似的题,都不会,现在知道是用KM算法做了 KM算法目 ...
- POJ 2157 Evacuation Plan [最小费用最大流][消圈算法]
---恢复内容开始--- 题意略. 这题在poj直接求最小费用会超时,但是题意也没说要求最优解. 根据线圈定理,如果一个跑完最费用流的残余网络中存在负权环,那么顺着这个负权环跑流量为1那么会得到更小的 ...
- POJ 2195 Going Home(最小费用最大流)
http://poj.org/problem?id=2195 题意 : N*M的点阵中,有N个人,N个房子.让x个人走到这x个房子中,只能上下左右走,每个人每走一步就花1美元,问当所有的人都归位了之 ...
随机推荐
- Coder-Strike 2014 - Finals (online edition, Div. 1)
CF 420A A. Start Up 题目链接: http://codeforces.com/problemset/problem/420/A 题目意思: 给一个字符串A,通过镜面反射后得到A', ...
- 将RDL报表转换成RDLC报表的函数
原文:将RDL报表转换成RDLC报表的函数 近日研究RDLC报表,发现其不能与RDL报表兼容,尤其是将RDL报表转换成RDLC报表.网上的资料贴出的的转换方式复杂且不切实际,遂决定深入研究.经研究发现 ...
- css3的calc() css3的百分比减宽,减高,加,乘,除,适合用于后台的排版定位
css3的calc() css3的百分比减宽,减高,加,乘,除,适合用于后台的排版定位 浏览器支持IE9+.FF4.0+.Chrome19+.Safari6+ calc()语法非常简单,就像我们小时候 ...
- C#基础加强篇----委托、Lamada表达式和事件(上)
1.委托 C#的委托相当于C/C++中的函数指针.函数指针用指针获取一个函数的入口地址,实现对函数的操作. 委托与C/C++中的函数指针不同在于,委托是面向对象的,是引用类型,对委托的使用要先定义后实 ...
- 【转载】动态载入DLL所需要的三个函数详解(LoadLibrary,GetProcAddress,FreeLibrary)
原文地址:https://www.cnblogs.com/westsoft/p/5936092.html 动态载入 DLL 动态载入方式是指在编译之前并不知道将会调用哪些 DLL 函数, 完全是在运行 ...
- intel汇编笔记
另一篇汇编学习笔记AT&T Assembly on Linux (linux下) mov ax,bx bx到ax 读数据过程:cpu通过地址线发送地址a,控制线向存储器发送读命令,存 ...
- 【Windows10 IoT开发系列】开发人员模式设置
原文:[Windows10 IoT开发系列]开发人员模式设置 声明:本文转自微软Windows 开发人员中心(https://msdn.microsoft.com/library/windows/ ...
- Android Studio 添加 Genymotion插件
原文:Android Studio 添加 Genymotion插件 1.下载Genymotion:官网地址,必须先注册才能下载,下载带有VirtualBox的版本 2.安装:安装时会连VirtualB ...
- 常见的几个Qt编程问题的处理(转自QT中文论坛)(挺实用的)
1.如何在窗体关闭前自行判断是否可关闭答:重新实现这个窗体的closeEvent()函数,加入判断操作 void MainWindow::closeEvent(QCloseEvent*event){i ...
- C++的 RTTI 观念和用途(非常详细)
自从1993年Bjarne Stroustrup [注1 ]提出有关C++ 的RTTI功能之建议﹐以及C++的异常处理(exception handling)需要RTTI:最近新推出的C++ 或多或少 ...