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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

朱 - 刘算法

發布時間:2025/5/22 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 朱 - 刘算法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

· 定義

  對于有向無環圖$G (V, E)$,類似最小生成樹的定義,有向圖最小樹形圖即在有向圖上查找總權值和最小的樹形圖(即有向邊的樹)。

· 朱 - 劉算法

  對于每個點先選取到達它的最小的邊,這樣可組成一個邊集E1,顯然,該邊集權值和最小,但不一定是樹。

  在該邊集上進行縮點,并判斷是否有解(是否有點無入度,或若有根無出度),在融會$G$中,記為G1

  當然,若此時沒有找到有向環且有解,說明在當前圖上已找到最小樹形圖,那么將原來的縮點解開,即除了當前樹形圖上的弧之外,將縮點內沒有與已知弧有相同終點的邊選出,如此構成了G的最小樹形圖。

  反之,則進行改邊:先省去縮點內邊;對于由縮點內出去的邊,保持原權值即可;對于進入縮點的邊,令Vs表示縮點點集,對于?v ∈ Vs,?u ? Vs,有<u, V> = <u, v> - v的最小入權邊,是因為這樣將權值相加的話,就相當于刪去了縮點中擁有相同終點的邊。

  這樣更改完點集與邊集,進行重復運算即可。

  對于無根樹,建立超級根節點即可。

  其中,復雜度$O (nm)$。

· 代碼

  (該代碼僅求最小權值總和,這樣是不需解開縮點的)

?

1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 5 using namespace std; 6 7 typedef long long LL; 8 9 const int MAXN = 100 + 10; 10 const int MAXM = 1e04 + 10; 11 12 const int INF = 0x7fffffff; 13 14 struct Edge { 15 int u, v; 16 int w; 17 18 Edge () {} 19 20 Edge (int fu, int fv, int fw) : 21 u (fu), v (fv), w (fw) {} 22 } ; 23 24 Edge Edges[MAXM]; 25 26 LL ans = 0; 27 28 int Inw[MAXN]; 29 int pre[MAXN]; 30 31 int Belong[MAXN]; 32 int Vis[MAXN]; 33 34 void Zhu_Liu (int root, int V, int E) { 35 while (true) { 36 for (int i = 1; i <= V; i ++) 37 Inw[i] = INF; 38 39 for (int i = 1; i <= E; i ++) { 40 int u = Edges[i].u; 41 int v = Edges[i].v; 42 int w = Edges[i].w; 43 44 if (u == v) 45 continue; 46 47 if (w < Inw[v]) { 48 Inw[v] = w; 49 pre[v] = u; 50 } 51 } 52 53 for (int i = 1; i <= V; i ++) 54 if (Inw[i] == INF && i != root) { 55 ans = - 1; 56 57 return ; 58 } 59 60 memset (Belong, - 1, sizeof (Belong)); 61 memset (Vis, - 1, sizeof (Vis)); 62 Inw[root] = 0; 63 64 int cnt = 0; 65 for (int i = 1; i <= V; i ++) { 66 ans += Inw[i]; 67 68 int pres = i; 69 while (Vis[pres] != i && Belong[pres] == - 1 && pres != root) { 70 Vis[pres] = i; 71 pres = pre[pres]; 72 } 73 74 if (Belong[pres] == - 1 && pres != root) { 75 cnt ++; 76 for (int p = pre[pres]; p != pres; p = pre[p]) 77 Belong[p] = cnt; 78 Belong[pres] = cnt; 79 } 80 } 81 82 if (! cnt) 83 break; 84 85 for (int i = 1; i <= V; i ++) 86 if (Belong[i] == - 1) 87 Belong[i] = ++ cnt; 88 89 for (int i = 1; i <= E; i ++) { 90 int u = Edges[i].u; 91 int v = Edges[i].v; 92 93 Edges[i].u = Belong[u]; 94 Edges[i].v = Belong[v]; 95 96 if (Belong[u] != Belong[v]) 97 Edges[i].w -= Inw[v]; 98 } 99 100 V = cnt; 101 root = Belong[root]; 102 } 103 } 104 105 int N, M, Root; 106 107 int Outdeg[MAXN]= {0}; 108 109 int main () { 110 scanf ("%d%d%d", & N, & M, & Root); 111 112 for (int i = 1; i <= M; i ++) { 113 int u, v, w; 114 scanf ("%d%d%d", & u, & v, & w); 115 116 Edges[i] = Edge (u, v, w); 117 Outdeg[u] ++; 118 } 119 120 if (! Outdeg[Root]) 121 ans = - 1; 122 else 123 Zhu_Liu (Root, N, M); 124 125 printf ("%lld\n", ans); 126 127 return 0; 128 } 129 130 /* 131 4 6 1 132 1 2 3 133 1 3 1 134 4 1 2 135 4 2 2 136 3 2 1 137 3 4 1 138 */ 139 140 /* 141 4 6 3 142 1 2 3 143 1 3 1 144 4 1 2 145 4 2 2 146 3 2 1 147 3 4 1 148 */ 149 150 /* 151 4 6 2 152 1 2 3 153 1 3 1 154 4 1 2 155 4 2 2 156 3 2 1 157 3 4 1 158 */ View Code

?

  

轉載于:https://www.cnblogs.com/Colythme/p/9710789.html

總結

以上是生活随笔為你收集整理的朱 - 刘算法的全部內容,希望文章能夠幫你解決所遇到的問題。

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