• 【洛谷 P1645】 序列 (差分约束)


    题目链接
    差分约束。
    (s[i])表示前(i)个位置有多少个数,那么对于一个限制条件((L,R,C)),显然有

    [s[R]-s[L-1]>=C ]

    于是连一条(L-1)(R)边权为(C)的边。
    但为了保证能从(0)走到(max(b)),我们还需从(1)(n),对(i-1)(i)连一条权为(0)的边,对(i)(i-1)连一条权为(-1)的边,
    这也很好理解,因为

    [s[i]-s[i-1]>=0,s[i-1]-s[i]>=-1 ]

    显然成立。
    然后从(0)(max(b))跑一遍最长路就好了。注意有正权边,所以不能跑Dijkstra,跑SPFA。

    #include <cstdio>
    #include <algorithm>
    #include <queue>
    #include <cstring>
    using namespace std;
    
    #define Open(s) freopen(s".in","r",stdin);freopen(s".out","w",stdout);
    #define Close fclose(stdin);fclose(stdout);
    const int MAXN = 1010;
    int n, a, b, c, r;
    struct Edge{
        int next, to, dis;
    }e[MAXN << 2];
    int head[MAXN], num;
    inline void Add(int from, int to, int dis){
        e[++num] = (Edge){ head[from], to, dis };
        head[from] = num;
    }
    queue <int> q;
    int dis[MAXN], vis[MAXN];
    int main(){
    	Open("sequence");
    	scanf("%d", &n);
    	for(int i = 1; i <= n; ++i){
    		scanf("%d%d%d", &a, &b, &c);
    		r = max(r, b);
            Add(a - 1, b, c);
    	}
    	for(int i = 1; i <= r; ++i)
    		Add(i - 1, i, 0), Add(i, i - 1, -1);
    	memset(dis, 128, sizeof dis); dis[0] = 0;
    	q.push(0);
    	while(!q.empty()){
          int now = q.front();
          q.pop();
          vis[now] = 0;
          for(int i = head[now]; i; i = e[i].next)
             if(dis[e[i].to] < dis[now] + e[i].dis){
               dis[e[i].to] = dis[now] + e[i].dis;
               if(!vis[e[i].to]) q.push(e[i].to), vis[e[i].to] = 1;
             }
        }
    	printf("%d
    ", dis[r]);
    	Close;
    	return 0;
    }
    
    
  • 相关阅读:
    类数组及其转换
    数组去重
    ios UIView
    ios 解决Wkwebview闪烁问题
    ios Https问题
    UUID
    JavaScript4
    JavaScript2
    JavaScript1
    UIScollView
  • 原文地址:https://www.cnblogs.com/Qihoo360/p/9685441.html
Copyright © 2020-2023  润新知