差分约束
挺好理解的 这个概念
博客 点我->😁
例题 poj 3169
1 /* 2 * @Promlem: 3 * @Time Limit: ms 4 * @Memory Limit: k 5 * @Author: pupil-XJ 6 * @Date: 2019-10-30 01:24:23 7 * @LastEditTime: 2019-10-30 01:43:52 8 */ 9 #include<iostream> 10 #include<stack> 11 #define rep(i, n) for(int i=0;i!=n;++i) 12 #define rep1(i, n) for(int i=1;i<=n;++i) 13 using namespace std; 14 const int INF = 0x3f3f3f3f; 15 const int MAXN = 1000+5; 16 const int MAXM = 20000+5; 17 18 int num; 19 int head[MAXN]; 20 struct node { 21 int v, next, w; 22 } edge[MAXM]; 23 24 inline void add(int x, int y, int w) { 25 edge[num].v = y; 26 edge[num].w = w; 27 edge[num].next = head[x]; 28 head[x] = num++; 29 } 30 31 int n, m1, m2; 32 33 int vis[MAXN], inq[MAXN], dis[MAXN]; 34 bool SPFA() { 35 rep1(i, n) vis[i] = inq[i] = 0, dis[i] = INF; 36 vis[1] = inq[1] = 1; 37 dis[1] = 0; 38 stack<int> st; 39 st.push(1); 40 while(!st.empty()) { 41 int u = st.top(); 42 st.pop(); 43 vis[u] = 0; 44 for(int i = head[u]; i != -1; i = edge[i].next) { 45 int v = edge[i].v; 46 if(dis[v] > dis[u] + edge[i].w) { 47 dis[v] = dis[u] + edge[i].w; 48 if(!vis[v]) { 49 vis[v] = 1; 50 st.push(v); 51 if(++inq[v] > n) return false; 52 } 53 } 54 } 55 } 56 return true; 57 } 58 59 int main() { 60 ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); 61 cin >> n >> m1 >> m2; 62 num = 0; 63 rep1(i, n) head[i] = -1; 64 int x, y, w; 65 rep(i, m1) { 66 cin >> x >> y >> w; 67 add(x, y, w); 68 } 69 rep(i, m2) { 70 cin >> x >> y >> w; 71 add(y, x, -w); 72 } 73 if(!SPFA()) cout << "-1\n"; 74 else if(dis[n] == INF) cout << "-2\n"; 75 else cout << dis[n] << endl; 76 return 0; 77 }
// poj 3159
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /* 2 * @Promlem: 3 * @Time Limit: ms 4 * @Memory Limit: k 5 * @Author: pupil-XJ 6 * @Date: 2019-10-27 15:10:27 7 * @LastEditTime: 2019-10-27 16:10:46 8 */ 9 #include<cstdio> 10 #include<cstring> 11 #include<cmath> 12 #include<iostream> 13 #include<string> 14 #include<algorithm> 15 #include<iomanip> 16 #include<vector> 17 #include<queue> 18 #include<stack> 19 #include<set> 20 #include<map> 21 #define read(n) n = read_n() 22 #define rep(i, n) for(int i=0;i!=n;++i) 23 #define per(i, n) for(int i=n-1;i>=0;--i) 24 #define Rep(i, sta, n) for(int i=sta;i!=n;++i) 25 #define rep1(i, n) for(int i=1;i<=n;++i) 26 #define per1(i, n) for(int i=n;i>=1;--i) 27 #define Rep1(i, sta, n) for(int i=sta;i<=n;++i) 28 #define L k<<1 29 #define R k<<1|1 30 #define mid (tree[k].l+tree[k].r)>>1 31 #define eps 1e-10 32 using namespace std; 33 const int INF = 0x3f3f3f3f; 34 typedef long long ll; 35 36 inline int read_n() { 37 char c=getchar();int x=0,f=1; 38 while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} 39 while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} 40 return x*f; 41 } 42 43 const int MAXN = 30000+5; 44 const int MAXM = 150000+5; 45 46 int num; 47 int head[MAXN]; 48 struct node {// 链式向前星 49 int v, next; 50 int w; 51 } edge[MAXM]; 52 53 inline void add(int x, int y, int w) { 54 edge[num].v = y; 55 edge[num].next = head[x]; 56 edge[num].w = w; 57 head[x] = num++; 58 } 59 60 int n, m; 61 int dis[MAXN], vis[MAXN], inq[MAXN]; 62 63 bool SPFA(int s) { 64 stack<int> q; 65 dis[s] = 0; 66 vis[s] = inq[s] = 1; 67 q.push(s); 68 while(!q.empty()) { 69 int u = q.top(); 70 q.pop(); 71 vis[u] = 0; 72 for(int i = head[u]; i != -1; i = edge[i].next) { 73 int v = edge[i].v; 74 if(dis[v] > dis[u] + edge[i].w) { 75 dis[v] = dis[u] + edge[i].w; 76 if(!vis[v]) { 77 q.push(v); 78 vis[v] = 1; 79 ++inq[v]; 80 if(inq[v] > n) return false; 81 } 82 } 83 } 84 } 85 return true; 86 } 87 88 int main() { 89 read(n); read(m); //cin >> n >> m; 90 int s, e, v; 91 num = 0; 92 for(int i = 1; i <= n; ++i) head[i] = -1, dis[i] = INF; 93 for(int i = 0; i != m; ++i) { 94 read(s); read(e); read(v); //cin >> s >> e >> v; 95 add(s, e, v); 96 } 97 if(SPFA(1)) cout << dis[n] << "\n"; 98 return 0; 99 }