poj 1201 Intervals 差分约束系统

题目链接: http://poj.org/problem?id=1201

题意:给定n(1<= n <= 50000)个 闭区间,每个区间后面带一个值 Ci, 问集合Z个数的最小值使得在每个区间中的数的个数 “不少于Ci”?

思路: S[i] 表示 小于等于i 的个数,这样可以直接按照输入建立不等式之后转化为有向网即可;

需要注意的是 在原始的两个不等式 S[i-1] - s[i] <= 0 和 s[i-1] - s[i] <= 1不宜在建边时就加入,这会使得有向网络中的边数达到3*(mx-mn)。

其实只需在处理完输入的边,线性改变单调性即可;

 

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<map>
#include<queue>
#include<vector>
#include<cmath>
#include<stdlib.h>
#include<time.h>
using namespace std;
#define rep0(i,l,r) for(int i = (l);i < (r);i++)
#define rep1(i,l,r) for(int i = (l);i <= (r);i++)
#define rep_0(i,r,l) for(int i = (r);i > (l);i--)
#define rep_1(i,r,l) for(int i = (r);i >= (l);i--)
#define MS0(a) memset(a,0,sizeof(a))
#define MS1(a) memset(a,-1,sizeof(a))
#define MSi(a) memset(a,0x3f,sizeof(a))
#define pb push_back
#define MK make_pair
#define A first
#define B second
#define clear0 (0xFFFFFFFE)
#define inf 0x3f3f3f3f
#define eps 1e-8
#define mod 1000000007
#define zero(x) (((x)>0?(x):-(x))<eps)
#define bitnum(a) __builtin_popcount(a)
#define lowbit(x) (x&(-x))
#define K(x) ((x)*(x))
typedef pair<int,int> PII;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
template<typename T>
void read1(T &m)
{
    T x = 0,f = 1;char ch = getchar();
    while(ch <'0' | ch >'9'){ if(ch == '-') f = -1;ch=getchar(); }
    while(ch >= '0' && ch <= '9'){ x = x*10 + ch - '0';ch = getchar(); }
    m = x*f;
}
template<typename T>
void read2(T &a,T &b){read1(a);read1(b);}
template<typename T>
void read3(T &a,T &b,T &c){read1(a);read1(b);read1(c);}
template<typename T>
void out(T a)
{
    if(a>9) out(a/10);
    putchar(a%10+'0');
}
inline ll gcd(ll a,ll b){ return b == 0? a: gcd(b,a%b); }
inline ll lcm(ll a,ll b){ return a/gcd(a,b)*b; }
template<class T1, class T2> inline void gmax(T1& a, T2 b){ if(a < b) a = b;}
template<class T1, class T2> inline void gmin(T1& a, T2 b){ if(a > b) a = b;}
const int maxn = 50001;
int tot, dist[maxn];
struct edge{
    int u, v, w;
    edge(){}
    edge(int u,int v,int w):u(u), v(v), w(w){}
}e[maxn];
int mx = 0, mn = inf;
bool bellman_ford()
{
    MS0(dist); //dist[mx] = 0;
    int flag = 1;
    while(flag){
        flag = 0;

        for(int j = 0; j < tot; j++){
            int u = e[j].u, v = e[j].v, w = e[j].w;
            if(dist[v] > dist[u] + w) dist[v] = dist[u] + w, flag = 1;
        }

        for(int j = mn; j < mx; j++) gmin(dist[j+1], dist[j]+1);
        for(int j = mx; j > mn; j--) gmin(dist[j-1], dist[j]);
    }
    return true;
}
int main()
{
    //freopen("data.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int n;
    read1(n); tot = 0;
    rep1(i, 1, n){
        int u, v, w;
        read3(u, v, w);
        e[tot++] = edge(v, u-1, -w);        // <v ,u-1, -w>
        gmin(mn, u-1);  gmax(mx, v);
    }
    bellman_ford();
    printf("%d\n", dist[mx] - dist[mn]);
    return 0;
}

 

posted @ 2016-08-07 10:06  hxer  阅读(206)  评论(0编辑  收藏  举报