码迷,mamicode.com
首页 > 其他好文 > 详细

UVA1723 Intervals

时间:2018-10-17 14:35:13      阅读:186      评论:0      收藏:0      [点我收藏+]

标签:interval   $0   条件   hid   eof   pac   get   ==   namespace   

这题$n$倍经验……

考虑差分约束:

我们设$s_i$表示$[-1, i]$这个区间中数字的种类数,那么一个条件的限制相当于$s_{b_i} - s_{a_i - 1} \leq c_i$,那么连边$(a_i - 1, b_i, c_i)$。

再挖掘一些隐含条件:$0 \leq s_i - s_{i - 1} \leq 1$,那么再连边$(i - 1, i, 0)$和$(i, i - 1, -1)$。

然后从$s_{-1}$开始跑最长路即可,因为题目中保证了$c_i \leq b_i - a_i + 1$,所以不会有正环,也就是说最后的$dis_{50000}$就是答案。

时间复杂度$O(spfa ???)$。

感觉这些最长路的题目反正要把边权倒过来,不如直接用最短路建模求解。

Code:

技术分享图片
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;

const int N = 50010;
const int M = 2e5 + 5;
const int Maxn = 50002;

int testCase, n, tot, head[N], dis[N];
bool vis[N];

struct Edge {
    int to, nxt, val;
} e[M];

inline void add(int from, int to, int val) {
    e[++tot].to = to;
    e[tot].val =val;
    e[tot].nxt = head[from];
    head[from] = tot;
}

inline void read(int &X) {
    X = 0; char ch = 0; int op = 1;
    for(; ch > 9 || ch < 0; ch = getchar())
        if(ch == -) op = -1;
    for(; ch >= 0 && ch <= 9; ch = getchar())
        X = (X << 3) + (X << 1) + ch - 48;
    X *= op;
}

queue <int> Q;
void spfa(int st) {
    memset(vis, 0, sizeof(vis));
    memset(dis, 0x3f, sizeof(dis));
    vis[st] = 1, dis[st] = 0;
    Q.push(st);
    for(; !Q.empty(); ) {
        int x = Q.front(); Q.pop();
        vis[x] = 0;
        for(int i = head[x]; i; i = e[i].nxt) {
            int y = e[i].to;
            if(dis[y] > dis[x] + e[i].val) {
                dis[y] = dis[x] + e[i].val;
                if(!vis[y]) {
                    vis[y] = 1;
                    Q.push(y);
                }
            }
        }
    }
}

int main() {
    for(read(testCase); testCase--; ) {
        read(n);
        tot = 0; memset(head, 0, sizeof(head));
        for(int x, y, v, i = 1; i <= n; i++) {
            read(x), read(y), read(v);
            x += 1, y += 2;
            add(x, y, -v);
        }
        for(int i = 1; i < Maxn; i++) add(i, i + 1, 0);
        for(int i = Maxn; i > 1; i--) add(i, i - 1, 1);

        spfa(1);

        printf("%d\n", -dis[Maxn]);
        if(testCase) printf("\n");
    }
    return 0;
}
View Code

 

UVA1723 Intervals

标签:interval   $0   条件   hid   eof   pac   get   ==   namespace   

原文地址:https://www.cnblogs.com/CzxingcHen/p/9803433.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!