Modules
题目链接:here
朱刘算法
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define LL long long 4 const int inf = 0x3f3f3f3f; 5 const int maxn = 3010; 6 const int maxe = 3010 * 2; 7 struct Edge{ 8 int u, v, w; 9 Edge(int u = 0, int v = 0, int w = 0) : u(u), v(v), w(w) {} 10 }e[maxe]; 11 12 int pre[maxn], id[maxn], vis[maxn]; 13 LL in[maxn]; 14 15 LL Dir_MST(int n, int m){ 16 int rt = 0; 17 LL ans = 0; 18 for(int i = 1; i <= n; i++) e[m++] = Edge(rt, i, 0); 19 n++; 20 int cnt = m; 21 while(true) { 22 for(int i = 0; i < n; i++) in[i] = -inf; 23 for(int i = 0; i < cnt; i++) { 24 int u = e[i].u, v = e[i].v, w = e[i].w; 25 if(w > in[v] && u != v) { 26 in[v] = w; 27 pre[v] = u; 28 } 29 } 30 int cntnode = 0; 31 memset(vis, -1, sizeof(vis)); 32 memset(id, -1, sizeof(id)); 33 in[rt] = 0; 34 for(int i = 0; i < n; i++){ 35 ans = ans + in[i]; 36 int v = i; 37 while(vis[v] != i && v != rt && id[v] == -1) { 38 vis[v] = i; 39 v = pre[v]; 40 } 41 if(id[v] == -1 && v != rt){ 42 for(int u = pre[v]; u != v; u = pre[u]) id[u] = cntnode; 43 id[v] = cntnode++; 44 } 45 } 46 if(cntnode == 0) break; 47 for(int i = 0; i < n; i++){ 48 if(id[i] == -1) id[i] = cntnode++; 49 } 50 for(int i = 0; i < cnt; i++){ 51 int v = e[i].v; 52 e[i].u = id[e[i].u]; 53 e[i].v = id[e[i].v]; 54 if(e[i].u != e[i].v) e[i].w -= in[v]; 55 } 56 n = cntnode; 57 rt = id[rt]; 58 } 59 return ans; 60 } 61 62 int main(){ 63 int t, n, m; 64 //freopen("in.txt", "r", stdin); 65 scanf("%d", &t); 66 while(t--) { 67 scanf("%d %d", &n, &m); 68 LL ans = 0; 69 int x; 70 for(int i = 0; i < n; i++) { 71 scanf("%d", &x); 72 ans += x; 73 } 74 int u, v, w; 75 for(int i = 0; i < m; i++){ 76 scanf("%d %d %d", &u, &v, &w); 77 e[i] = Edge(v, u, w); 78 } 79 printf("%lld\n", Dir_MST(n, m) + ans); 80 } 81 return 0; 82 }