最小树形图,朱刘算法 可以看一下这个: http://blog.csdn.net/wsniyufang/article/details/6747392
#include<iostream> #include<string> #include<cstdio> #include<set> #include<stack> #include<list> #include<vector> #include<queue> #include<algorithm> #include<cstring> #include<cmath> #include<fstream> using namespace std; typedef long long ll; const int maxn = 1010,maxe = 40010,INF = 0x3f3f3f3f; int n,m; int in[maxn],pre[maxn],id[maxn],vis[maxn]; struct node{ int u,v,w; bool operator < (const node &a) const{ return w < a.w; } }; node e[maxe]; int build(int n,int m,int root){ int ans = 0; while(1){ memset(in,INF,sizeof in); memset(pre,-1,sizeof pre); //1.选择入边 for(int i = 0;i < m;++i){ int u = e[i].u,v = e[i].v,w = e[i].w; if (in[v] > w && u != v){ in[v] = w; pre[v] = u; } } for(int i = 0;i < n;++i){ if (i == root) continue; if (in[i] == INF) return -1; } in[root] = 0; //2.找环缩点 memset(id,-1,sizeof id); memset(vis,-1,sizeof vis); int cnt = 0; for(int i = 0;i < n;++i){ ans += in[i]; int v = i; while(vis[v] != i && v != root && id[v] == -1){ vis[v] = i; v = pre[v]; } if(v != root && id[v] == -1){ for(int u = pre[v];u != v;u = pre[u]) id[u] = cnt; id[v] = cnt++; } } if (cnt == 0) break; for(int i = 0;i < n;++i) if (id[i] == -1) id[i] = cnt++; //3.重新建图 for(int i = 0;i < m;++i){ int u = e[i].u,v = e[i].v; e[i].u = id[u],e[i].v = id[v]; if (u != v) e[i].w -= in[v]; } n = cnt; root = id[root]; } return ans; } void init(){ cin >> n >> m; int a,b,c; memset(e,0,sizeof e); for(int i = 0;i < m;++i){ cin >> a >> b >> c; e[i] = {a,b,c}; } int t = build(n,m,0); if (t == -1) cout << "Possums!" << endl; else cout << t << endl; } int main(){ int t; cin >> t; for(int k = 0;k < t;++k){ cout << "Case #" << k+1 << ": "; init(); } }