• 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
  • 相关阅读:
    ios 数据类型转换 UIImage转换为NSData NSData转换为NSString
    iOS UI 12 block传值
    iOS UI 11 单例
    iOS UI 08 uitableview 自定义cell
    iOS UI 07 uitableviewi3
    iOS UI 07 uitableviewi2
    iOS UI 07 uitableview
    iOS UI 05 传值
    iOS UI 04 轨道和动画
    iOS UI 03 事件和手势
  • 原文地址:https://www.cnblogs.com/zhengguiping--9876/p/5813907.html
Copyright © 2020-2023  润新知