zoukankan      html  css  js  c++  java
  • 关于最短路、负环、差分约束系统的一点笔记

    关于最短路、负环、差分约束系统的一点笔记

    最短路

    “可以”没有环,最多(|V|-1)条边

    有负环则不存在最短路

    会形成最短路径树

    算法

    1. Dijkstra 贪心,当(d_u)是最小时要满足之后(d_u)不会更小,不能处理负权边
    2. Bellman-Ford 迭代n-1轮,用边松弛
    3. spfa 队列优化的Bellman-Ford

    最短路的线性规划形式

    最大化 (d_i)

    满足

    1. 三角不等式 $d_v le d_u + w(u,v), $
    2. (d_s=0)

    说明:上述约束对应了无穷组解。最短路求的是满足约束的最大值。因为三角不等式要求取等号时w(u,v)是最短路上的边。

    应用

    差分约束系统

    非DAG上DP

    一般使用spfa或者缩点后dp

    应为dijkstra有贪心策略的限制

    负环

    将所有点入队,且(d_i=0)

    负环只看不等约束,不看初始值

    算法

    1. Bellman-Ford 常数小
    2. spfa 判断 1. 入队次数>=n 2.最短路长度>=n
    3. spfa-dfs 没多大意思,轻松被卡

    应用

    01分数规划

    代码

    见最后

    差分约束系统

    和最短路的线性规划形式类似的一类线性规划问题

    也是需要初值的,对应d[s]=0

    最短路

    最大化

    有负环则无解

    图不连通 无关 任意解

    最长路

    最小化

    有正环则无解

    图不连通 无关 任意解

    当然也可以转化成最短路


    附录:

    判负环的代码

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    using namespace std;
    const int N = 2005, M = 3005;
    
    inline int read() {
    	int x = 0, f = 1; char c = getchar();
    	while(c<'0' || c>'9') {if(c=='-') f=-1; c=getchar();}
    	while(c>='0' && c<='9') {x=x*10+c-'0'; c=getchar();}
    	return x * f;
    }
    
    int n, m;
    struct edge {int v, ne, w, u;} e[M<<1];
    int cnt, h[N];
    inline void ins(int u, int v, int w) {
    	e[++cnt] = (edge) {v, h[u], w, u}; h[u] = cnt;
    }
    
    int d[N], cou[N];
    bool bellman_ford() {
    	for(int i=1; i<=n; i++) d[i] = cou[i] = 0;
    	for(int i=1; i<=n; i++) {
    		for(int i=1; i<=cnt; i++) {
    			int u = e[i].u, v = e[i].v; //printf("hi %d %d  %d %d
    ", u, v, d[u], d[v]);
    			if(d[v] > d[u] + e[i].w) {
    				d[v] = d[u] + e[i].w;
    				cou[v] = cou[u] + 1;
    				if(cou[v] >= n) return false;
    				if(i == n) return false;
    			}
    		}
    	}
    	return true;
    }
    int main() {
    	freopen("in", "r", stdin);
    	int T = read();
    	while(T--) {
    		cnt = 0; memset(h, 0, sizeof(h));
    
    		n = read(); m = read();
    		for(int i=1; i<=m; i++) {
    			int u = read(), v = read(), w = read();
    			if(w < 0) ins(u, v, w);
    			else ins(u, v, w), ins(v, u, w);
    		}
    		puts(bellman_ford() ? "N0" : "YE5");
    	}
    }
    
    
    
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    using namespace std;
    const int N = 2005, M = 3005;
    
    inline int read() {
    	int x = 0, f = 1; char c = getchar();
    	while(c<'0' || c>'9') {if(c=='-') f=-1; c=getchar();}
    	while(c>='0' && c<='9') {x=x*10+c-'0'; c=getchar();}
    	return x * f;
    }
    
    int n, m;
    struct edge {int v, ne, w;} e[M<<1];
    int cnt, h[N];
    inline void ins(int u, int v, int w) {
    	e[++cnt] = (edge) {v, h[u], w}; h[u] = cnt;
    }
    int d[N], cou[N], inq[N], cinq[N];
    int q[N], head, tail;
    inline void lop(int &x) {if(x==N) x=1;}
    bool spfa() {
    	head = tail = 1;
    	for(int i=1; i<=n; i++) d[i] = cou[i] = 0, inq[i] = cinq[i] = 1, q[tail++] = i;
    	while(head != tail) {
    		int u = q[head++]; lop(head); inq[u] = 0;
    		for(int i=h[u]; i; i=e[i].ne) {
    			int v = e[i].v;
    			if(d[v] > d[u] + e[i].w) {
    				d[v] = d[u] + e[i].w;
    				cou[v] = cou[u] + 1;
    				if(cou[v] >= n) return false;
    				if(!inq[v]) {
    					q[tail++] = v; lop(tail); inq[v] = 1; 
    					if(++cinq[v] >= n) return false; 
    				}
    			}
    		}
    	}
    	return true;
    }
    
    int main() {
    	freopen("in", "r", stdin);
    	int T = read();
    	while(T--) {
    		cnt = 0; memset(h, 0, sizeof(h));
    
    		n = read(); m = read();
    		for(int i=1; i<=m; i++) {
    			int u = read(), v = read(), w = read();
    			if(w < 0) ins(u, v, w);
    			else ins(u, v, w), ins(v, u, w);
    		}
    		puts(spfa() ? "N0" : "YE5");
    	}
    }
    
    
  • 相关阅读:
    E
    D
    C
    B
    Python
    IDEA 设置资源目录
    光猫指示灯含义
    IO模型
    Linux 总目录
    Linux python 使用
  • 原文地址:https://www.cnblogs.com/candy99/p/9282113.html
Copyright © 2011-2022 走看看