UVA Intervals
Description
- 有n个区间,在区间[ai,bi]中至少取任意互不相同的ci个整数。求在满足n个区间的情况下,至少要取多少个正整数。
Input
多组数据。
第一行的一个整数T表示数据个数,后面有一行空行。
对于每组数据:
第一行包含一个整数n(1<=n<=50000)表示区间数。
以下n行描述区间。
输入的第(i+1)行包含三个整数ai,bi,ci,由空格分开。其中0<=ai<=bi<=50000,1<=ci<=bi-ai+1。
Output
对于每组数据,输出一个对于n个区间[ai,bi] 至少取ci个不同整数的数的总个数。
在除了最后一组数据后输出空行。
Sample Input
1 5 3 7 3 8 10 3 6 8 1 1 3 1 10 11 1
Sample Output
6
题解:
- 差分约束。
- 当你做完洛谷P1250种树再做这题时,你会大叫一声:“啊!原题”
- 其实本质是一样的。
- 所以本篇的题解转那篇
还有,为什么这么简单是紫题... ...
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#define N 200005
using namespace std;
struct E {int next, to, dis;} e[N];
int T, m, num, n;
int h[N], dis[N];
bool vis[N];
int read()
{
int x = 0; char c = getchar();
while(c < '0' || c > '9') c = getchar();
while(c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = getchar();}
return x;
}
void add(int u, int v, int w)
{
e[++num].next = h[u];
e[num].to = v;
e[num].dis = w;
h[u] = num;
}
void spfa()
{
queue<int> que;
memset(dis, -0x3f, sizeof(dis));
memset(vis, 0, sizeof(vis));
dis[n + 1] = 0, vis[n + 1] = 1, que.push(n + 1);
while(!que.empty())
{
int now = que.front();
que.pop(); vis[now] = 0;
for(int i = h[now]; i != 0; i = e[i].next)
if(dis[now] + e[i].dis > dis[e[i].to])
{
dis[e[i].to] = dis[now] + e[i].dis;
if(!vis[e[i].to])
vis[e[i].to] = 1, que.push(e[i].to);
}
}
}
int main()
{
cin >> T;
for(int dfn = 1; dfn <= T; dfn++)
{
n = num = 0;
memset(h, 0, sizeof(h));
m = read();
for(int i = 1; i <= m; i++)
{
int a = read(), b = read(), c = read();
add(a - 1, b, c), n = max(n, b);
}
for(int i = 1; i <= n; i++) add(i - 1, i, 0), add(i, i - 1, -1);
for(int i = 0; i <= n; i++) add(n + 1, i, 0);
spfa();
printf("%d\n", dis[n]);
if(dfn != T) printf("\n");
}
return 0;
}