http://poj.org/problem?id=1201
TLE了很久,因为用了cin.....
思路和其他差分约束差不多,http://www.cppblog.com/menjitianya/archive/2015/11/19/212292.html
如果区间[a, b]中至少有c个元素,如果用上面的博客,那么说明xa - xb >= c,但是注意这里是闭区间,xa - xb是不包括b这个点的,
就比如用了[a, b]有c个元素,[b, d]有x个,那么ans = c + x - 1个,因为有一个点是重合了的。
为了解决这个问题,重新定义,令xa - x(b+1) >= c代表区间[a, b]拥有的数量,其实这是显然的,只不过刚开始习惯用xa - xb代表[a, b]
没想到-xb是不包括b的。
这里还有一个问题就是区间不连续,所以跑不了最长路的问题。
[1, 4] >= 2 [6, 7] >= 2
无法跑spfa
所以要加边:
[3, 3]拥有的数量是 >= 0 <= 1的,
所以
x3 - x4 >= 0
x3 - x4 <= 1
的
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <assert.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;
#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <bitset>
#include <time.h>
#include <iomanip>
const int maxn = 2e5 + 20;
struct Edge {
int u, v, w, tonext;
}e[maxn * 2];
int num, first[maxn];
void addEdge(int u, int v, int w) {
++num;
e[num].u = u, e[num].v = v, e[num].w = w, e[num].tonext = first[u];
first[u] = num;
}
queue<int> que;
int in[maxn], dis[maxn], tim[maxn];
bool spfa(int bx, int n) { //从bx开始,有n个顶点
for (int i = 1; i <= n; ++i) {
dis[i] = inf;
tim[i] = 0; //入队次数清0
in[i] = false; //当前这个节点不在队列里
}
while (!que.empty()) que.pop();
que.push(bx), in[bx] = true, dis[bx] = 0, tim[bx]++;
while (!que.empty()) {
int u = que.front();
if (tim[u] > n) return true; //入队次数超过n次,出现负环
que.pop(); //in[u] = false ?
for (int i = first[u]; i; i = e[i].tonext) {
if (dis[e[i].v] > dis[e[i].u] + e[i].w) {
dis[e[i].v] = dis[e[i].u] + e[i].w;
if (!in[e[i].v]) { //不在队列
que.push(e[i].v);
in[e[i].v] = true;
tim[e[i].v]++;
}
}
}
in[u] = false;
}
return false;
}
void work() {
// memset(first, -1, sizeof first);
int n;
cin >> n;
int mx = 0;
for (int i = 1; i <= n; ++i) {
int u, v, w;
cin >> u >> v >> w;
// if (u > v) swap(u, v);
++u; ++v;
++v;
mx = max(mx, v);
addEdge(u, v, -w);
}
for (int i = 1; i < mx; ++i) {
addEdge(i, i + 1, 0);
addEdge(i + 1, i, 1);
}
spfa(1, mx);
// cout << spfa(1, mx) << endl;
cout << -dis[mx] << endl;
// printf("%d\n", -dis[mx + 1]);
}
int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
IOS;
work();
return 0;
}
View Code
标签:num,int,1201,++,Intervals,POJ,que,include,dis From: https://blog.51cto.com/u_15833059/5779560