• POJ-1201/HDU-1384 Intervals


    题目大意:

    有一个整数集合Z,现在给出n个整数区间[a,b]以及|Z∩[a,b]|的最少个数c,让你求这个整数集合的最小有多少

    解题思路:

    差分约束系统+spfa

    差分约束系统事实上就是一个构图的过程

    比如说现在有n个不等式

    X1 - X2 <= a

    X2 - X3 <= b

    ...

    X(n-1) - Xn <= ggg

    假如现在问你Xn - X1的最小值是多少,如何求解?

    首先这些式子必然会有两种情况,一种是必然没有解,一种是无数解

    对于有无数解的情况,必然是存在一种情况满足最小解,其实根据上面这些不等式很容易知道X1 - Xn <= a + b + ... + ggg那么答案就出来了。

    那么根据推广之后的式子该怎么解呢?

    首先根据这些式子构建有向图,但是这个有向图是可能存在重边,存在负权边的情况,那么只需要通过spfa算法计算从点1到点n的最小距离就解出来了。

    如果这个图存在负环的时候,就说明这个解不存在。

    差分约束就是这样的一种思想。

    代码:

    #include <queue>
    #include <cstdio>
    #include <vector>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    typedef struct node{
        int to, w;
        node(int a = 0, int b = 0){
            to = a; w = b;
        }
    }Edge;
    
    const int INF = 0x3f3f3f3f;
    const int maxn = 51000;
    
    vector<Edge> vec[maxn];
    int vis[maxn], dis[maxn];
    
    int spfa(int s, int e){
        int p, len; Edge nxt;
    
        queue<int> q;
        while(!q.empty()) q.pop();
        for(int i = 0; i <= e; ++i){
            vis[i] = 0;
            dis[i] = INF;
        }
    
        q.push(s); vis[s] = 1; dis[s] = 0;
        while(!q.empty()){
            p = q.front();
            q.pop();
    
            len = vec[p].size();
            for(int i = 0; i < len; ++i){
                nxt = vec[p][i];
                if(dis[p] + nxt.w < dis[nxt.to]){
                    dis[nxt.to] = dis[p] + nxt.w;
                    if(!vis[nxt.to]){
                        vis[nxt.to] = 1;
                        q.push(nxt.to);
                    }
                }
            }
            vis[p] = 0;
        }
        return -dis[e];
    }
    int main(){
        int n, a, b, c;
        while(~scanf("%d", &n)){
            int be = INF, en = 0;
            for(int i = 0; i < maxn; ++i) vec[i].clear();
            for(int i = 0; i < n; ++i){
                scanf("%d%d%d", &a, &b, &c);
                vec[a-1].push_back(Edge(b,-c));
                be = min(be, a);
                en = max(en, b);
            }
            for(int i = be - 1; i < en; ++i){
                vec[i].push_back(Edge(i+1, 0));
                vec[i+1].push_back(Edge(i, 1));
            }
            printf("%d
    ", spfa(be - 1, en));
        }
        return 0;
    }


  • 相关阅读:
    learnyou 相关网站
    hdu 3038 How Many Answers Are Wrong
    hdu 3047 Zjnu Stadium 并查集高级应用
    poj 1703 Find them, Catch them
    poj 1182 食物链 (带关系的并查集)
    hdu 1233 还是畅通工程
    hdu 1325 Is It A Tree?
    hdu 1856 More is better
    hdu 1272 小希的迷宫
    POJ – 2524 Ubiquitous Religions
  • 原文地址:https://www.cnblogs.com/wiklvrain/p/8179429.html
Copyright © 2020-2023  润新知