Intervals---poj1201(差分约束系统)

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

题目说[ai, bi]区间内和点集Z至少有ci个共同元素,那也就是说如果我用Si表示区间[0,i]区间内至少有多少个元素的话,那么Sbi - Sai >= ci,这样我们就构造出来了一系列边,权值为ci,但是这远远不够,因为有很多点依然没有相连接起来(也就是从起点可能根本就还没有到终点的路线),此时,我们再看看Si的定义,也不难写出0<=Si - Si-1<=1的限制条件,虽然看上去是没有什么意义的条件,但是如果你也把它构造出一系列的边的话,这样从起点到终点的最短路也就顺理成章的出现了。

我们将上面的限制条件写为同意的形式:

Sbi - Sai >= ci

Si - Si-1 >= 0

Si-1 - Si >= -1

因为要求的是最小有多少个,所以要求最长路;

所以求出图中最小点到最大点的最大距离即可;

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <queue>
#include <stack>
#include <algorithm>
#include <map>
#include <string>
typedef long long LL;
#define INF 0x3f3f3f3f
#define met(a, b) memset(a, b, sizeof(a))
#define N 51500

using namespace std;

int S, E, vis[N], dist[N];
struct node
{
    int u, v, w, Next;
}e[N*3];

int Head[N], cnt;

void Add(int u, int v, int w)
{
    e[cnt].v = v;
    e[cnt].w = w;
    e[cnt].Next = Head[u];
    Head[u] = cnt++;
}

int spfa()
{
    for(int i=0; i<=E; i++)
        dist[i] = -INF;
    met(vis, 0);
    queue<int> Q;
    Q.push(S);
    vis[S] = 1;
    dist[S] = 0;
    while(!Q.empty())
    {
        int p = Q.front();Q.pop();
        vis[p] = 0;
        for(int i=Head[p]; i!=-1; i=e[i].Next)
        {
            int q = e[i].v;
            if(dist[q] < dist[p]+e[i].w)///最长路;
            {
                dist[q] = dist[p]+e[i].w;
                if(!vis[q])
                {
                    vis[q] = 1;
                    Q.push(q);
                }
            }
        }
    }
    return dist[E];
}

int main()
{
    int n, u, v, w;
    while(scanf("%d", &n) != EOF)
    {
        met(e, 0);
        met(Head, -1);
        cnt = 0;
        S = INF; E = -INF;///找到对应的起点和终点;
        for(int i=1; i<=n; i++)
        {
            scanf("%d %d %d", &u, &v, &w);
            Add(u, v+1, w);///u可能等于0,所以v+1比较好;
            S = min(u, S);
            E = max(v+1, E);
        }
        for(int i=S; i<E; i++)///建立其他边,所以e要开3倍的N;
        {
            Add(i, i+1, 0);
            Add(i+1, i, -1);
        }
        int ans = spfa();
        printf("%d
", ans);
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/zhengguiping--9876/p/5813907.html