日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

算法提高课-图论-差分约束- AcWing 1169. 糖果:spfa求单源最短路、差分约束

發布時間:2025/4/5 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 算法提高课-图论-差分约束- AcWing 1169. 糖果:spfa求单源最短路、差分约束 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

      • 題目分析
      • 題目鏈接

題目分析



來源:acwing
分析:

差分約束系統

差分約束系統是一種特殊的N元一次不等式組。它包含N個變量X1,...,XnX_1,...,X_nX1?,...,Xn? 以及M個約束條件,每個約束條件都是由兩個變量作差構成的,形如Xi?Xj≤ckX_i-X_j \leq c_kXi??Xj?ck?,其中ckc_kck?是常數,我們要解決的問題是:求得一組X的解,值得所有約束條件都得到滿足。

對約束條件Xi?Xj≤ckX_i-X_j \leq c_kXi??Xj?ck?進行變形,就可以得到Xi≤Xj+ckX_i \leq X_j+c_kXi?Xj?+ck?,這與單源最短路徑問題中的三角不等式dist[y]≤dist[x]+zdist[y] \leq dist[x] + zdist[y]dist[x]+z很相似。因此,可以把每個變量XiX_iXi?看作有向圖中的一個結點i,對于每個約束條件Xi?Xj≤ckX_i-X_j \leq c_kXi??Xj?ck?,從結點j向結點i連一條長度為ckc_kck?的有向邊。

所以說,每個差分約束問題可以轉換為圖論的單源最短路問題。

單源最短路徑中源點需要滿足的條件:
從源點出發,必須可以遍歷到所有的邊。因為只有這樣才能滿足上述的三角不等式。

求解步驟:

  • 先將每個不等式Xi≤Xj+ckX_i \leq X_j+c_kXi?Xj?+ck?,轉換為一條從xj到xi,長度為ckc_kck?的有向邊。
  • 找到一個超級源點,該源點一定可以遍歷到所有邊。
  • 從源點求一遍單源最短路。
    如果存在負環,則原不等式組一定無解。
    如果無負環,則dist[]數組就是原不等式組的一個可行解。
  • 對應到本題。

    求的是最小值,要用最長路。

    ac代碼

    #include<bits/stdc++.h> using namespace std; typedef long long LL;const int N = 100100, M = 300010; int n, m; int h[N], e[M], w[M], ne[M], idx; LL dist[N]; int q[N], cnt[N]; // 用來求正環 bool st[N];void add(int a, int b, int c){e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++; }bool spfa(){int hh = 0, tt = 1;memset(dist, -0x3f, sizeof dist);dist[0] = 0; // 0號點是超級源點q[0] = 0;st[0] = true;while(hh != tt){int t = q[ -- tt]; // 用棧優化st[t] = false;for(int i = h[t]; ~i; i = ne[i]){int j = e[i];if(dist[j] < dist[t] + w[i]){dist[j] = dist[t] + w[i];cnt[j] = cnt[t] + 1;if(cnt[j] >= n + 1) return false;if(!st[j]){q[tt ++] = j;st[j] = true;}}}}return true; }int main(){memset(h, -1, sizeof h);cin >> n >> m;if(m == 0){cout << n << endl;return 0;}for(int i = 1; i <= n; i ++) add(0, i, 1);while( m --){int x, a, b;cin >> x >> a >> b;if( x == 1) add(b, a, 0), add(a, b, 0);else if(x == 2) add(a, b, 1);else if( x == 3) add(b, a, 0);else if( x == 4) add(b, a , 1);else add(a, b, 0);}if(!spfa()) puts("-1");else{LL res = 0;for(int i = 1; i <= n; i ++) res += dist[i];cout << res << endl;} }

    題目鏈接

    https://www.acwing.com/problem/content/1171/

    總結

    以上是生活随笔為你收集整理的算法提高课-图论-差分约束- AcWing 1169. 糖果:spfa求单源最短路、差分约束的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。