【题解】Intervals
题目大意
有\(n\)个区间(\(1 \leq n \leq 200\)),第\(i\)个区间覆盖\((a_{i}, b_{i})\)且有权值\(w_{i}\)(\(1 \leq a_{i} < b_{i} \leq 100000\),\(1 \leq w_{i} \leq 100000\)),每个点最多能被覆盖\(k\)次(\(1 \leq k \leq n\)),求最大的权值和为多少。
题解
这里点的坐标很大,所以我们要先离散化,顺便把每个点按照坐标排序。
排完序后,我们可以从\(a_{i}\)向\(b_{i}\)连一条有向边,容量为\(1\),费用为\(w_{i}\)。
同时,对于每个点\(i\)(\(0 \leq i \leq cnt\),其中\(cnt\)表示离散化后的点数,点\(0\)为源点\(s\),点\(cnt + 1\)为汇点\(t\)),我们要从点\(i\)向点\(i + 1\)连一条有向边,容量为\(k\),费用为\(0\)。
建完图后,直接跑最大费用流即可。具体细节可以参考下面的代码。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#define MAX_N (209 + 5)
#define INF 0x3f3f3f3f
using namespace std;
struct Edge
{
int to;
int weight;
int cost;
int next;
};
int T;
int n, k;
int s, t;
int hash[100005], cnt;
int h[MAX_N << 1], tot;
Edge e[MAX_N << 3];
int dis[MAX_N << 1];
int cur[MAX_N << 1];
bool inque[MAX_N << 1], vis[MAX_N << 1];
queue <int> q;
int maxflow, mincost;
inline void AddEdge(int u, int v, int w, int c)
{
e[++tot].to = v;
e[tot].weight = w;
e[tot].cost = c;
e[tot].next = h[u];
h[u] = tot;
return;
}
bool SPFA()
{
memset(dis, 0x3f, sizeof dis);
memset(inque, 0, sizeof inque);
memcpy(cur, h, sizeof cur);
q.push(s);
dis[s] = 0;
inque[s] = true;
int u, v, w, c;
while(!q.empty())
{
u = q.front();
q.pop();
inque[u] = false;
for(int i = h[u]; i; i = e[i].next)
{
v = e[i].to;
w = e[i].weight;
c = e[i].cost;
if(dis[v] > dis[u] + c && w)
{
dis[v] = dis[u] + c;
if(!inque[v])
{
inque[v] = true;
q.push(v);
}
}
}
}
return dis[t] != INF;
}
int DFS(int u, int flow)
{
vis[u] = true;
if(u == t)
{
maxflow += flow;
mincost += flow * dis[t];
return flow;
}
int v, w, c;
int tmp, sum = 0;
for(int i = cur[u]; i && sum < flow; i = e[i].next)
{
cur[u] = i;
v = e[i].to;
w = e[i].weight;
c = e[i].cost;
if(!vis[v] && dis[v] == dis[u] + c && w)
{
tmp = DFS(v, min(flow - sum, w));
e[i].weight -= tmp;
e[i ^ 1].weight += tmp;
sum += tmp;
}
}
return sum;
}
void Dinic()
{
while(SPFA())
{
do
{
memset(vis, 0, sizeof vis);
DFS(s, k);
}
while(vis[t]);
}
return;
}
int main()
{
scanf("%d", &T);
while(T--)
{
memset(h, 0, sizeof h);
memset(e, 0, sizeof e);
memset(hash, 0, sizeof hash);
cnt = 0;
tot = 1;
maxflow = mincost = 0;
scanf("%d%d", &n, &k);
int u[MAX_N], v[MAX_N], c[MAX_N];
int a[MAX_N << 1];
for(int i = 1; i <= n; ++i)
{
scanf("%d%d%d", &u[i], &v[i], &c[i]);
a[i] = u[i];
a[i + n] = v[i];
}
sort(a + 1, a + n + n + 1);
for(int i = 1; i <= n + n; ++i)
{
if(a[i] != a[i - 1]) hash[a[i]] = ++cnt;
}
for(int i = 1; i <= n; ++i)
{
u[i] = hash[u[i]];
v[i] = hash[v[i]];
AddEdge(u[i], v[i], 1, -c[i]);
AddEdge(v[i], u[i], 0, c[i]);
}
for(int i = 1; i < cnt; ++i)
{
AddEdge(i, i + 1, k, 0);
AddEdge(i + 1, i, 0, 0);
}
s = 0;
t = cnt + 1;
AddEdge(s, 1, k, 0);
AddEdge(1, s, 0, 0);
AddEdge(cnt, t, k, 0);
AddEdge(t, cnt, 0, k);
Dinic();
printf("%d\n", -mincost);
}
return 0;
}
【题解】Intervals的更多相关文章
- [LeetCode]题解(python):056-Merge Intervals
题目来源 https://leetcode.com/problems/merge-intervals/ Given a collection of intervals, merge all overl ...
- 【题解】【区间】【二分查找】【Leetcode】Insert Interval & Merge Intervals
Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessa ...
- LeetCode 题解 56. Merge Intervals
题目大意:给出一组区间,合并他们. 首先是排序,首先看start,start小的在前面.start相同的话,end小的在前面. 排序以后,要合并了. 我自己的笨方法,说实在的问题真的很多.提交了好几次 ...
- leetcode个人题解——#56 Merge Intervals
思路,先按照结构体中start进行排序,然后遍历比较前后项是否有重合. 第一次用到三参数形式的sort(),第三个参数的bool函数要写到类外才通过. /** * Definition for an ...
- 【LeetCode】Merge Intervals 题解 利用Comparator进行排序
题目链接Merge Intervals /** * Definition for an interval. * public class Interval { * int start; * int e ...
- HDOJ1384 Intervals 题解
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1384 大意:有 \(n\) 个区间 \([a_i,b_i]\),每个区间有个权值 \(c_i\),找到 ...
- 题解-The Number of Good Intervals
题面 The Number of Good Intervals 给定 \(n\) 和 \(a_i(1\le i\le n)\),\(m\) 和 \(b_j(1\le j\le m)\),求对于每个 \ ...
- 【题解】 POJ 1201 Intervals(差分约束)
懒得复制,戳我戳我 Solution: 这道题就是一个板子题 抽象成第\(a\)至第\(b\)间选择数的个数为\(c\),我们就可以用前缀和来表示,这样就可以得到不等式\(s[b]-s[a-1]> ...
- POJ1375:Intervals——题解
http://poj.org/problem?id=1375 题目大意:有一盏灯,求每段被圆的投影所覆盖的区间. —————————————————————— 神题,卡精度,尝试用各种方法绕过精度都不 ...
随机推荐
- 自制悬浮框,愉快地查看栈顶 Activity
接手陌生模块时,如何快速了解每个页面对应的类,以及它们之间的跳转逻辑.总不能在代码里一个一个地找startActivity()吧? 有时候,又想查看别人的 app 的页面组织(像淘宝.微信啊),总不能 ...
- MySQL 保存镜像实战操作( 拷贝方法 )
查看数据保存的位置 docker inspect --format='{{.Mounts}}' mxg_mysql 容器路径为:`/var/lib/mysql` ,宿主机数据保存在: /var/lib ...
- Linux手册页内容
总用9页 man1:可执行程序或shell命令 man2:系统调用(kernel提供的函数) man3:库调用(程序库中的函数) man4:/dev中的特殊文件 ...
- 线程工具类 - Semaphore(信号量)
Semaphore官方文档 一.使用信号量实现线程间的通信 /** * Demo:使用信号量实现线程间通信*/ public class SemaphoreDemo { public static v ...
- springboot 中的 thymeleaf 页面进阶小知识
我们做好了登录页,那设计一个场景吧,比如我们登录后跳转到公司主页,想从公司主页再跳转到员工列表页: 这样的场景我们该如何实现,首先要知道一些基础知识,就是SpringBoot的一些关于请求的架构知识: ...
- NOIP2015 提高组 Day T3 斗地主
题目描述 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共5张牌来进行的扑克牌游戏.在斗地主中,牌的大小关 系根据牌的数码表示如下:3<4< ...
- LDD3 第15章 内存映射和DMA
本章内容分为三个部分: 第一部分讲述了mmap系统调用的实现过程.将设备内存直接映射到用户进程的地址空间,尽管不是所有设备都需要,但是能显著的提高设备性能. 如何跨越边界直接访问用户空间的内存页,一些 ...
- js请求解析xml
xml数据 <?xml version="1.0" encoding="utf-8"?> <table> <node name=& ...
- vue项目中使用element的dialog中引入ztree却不能初始化解决办法
一开始我在 里边写的,发现获取不到,那么采用dialog自带的回调函数,窗口打开后opend进行处理, 结果:
- Trailing Zeroes (III) -;lightoj 1138
Trailing Zeroes (III) PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 MB Y ...