最小树形图模板题
#include <iostream> #include <algorithm> #include <cstdio> #include <cstdlib> #include <cstring> #include <string> #include <stack> #include <queue> #include <cmath> #include <vector> using namespace std; typedef long long LL; const int N=1e3+5; const int INF=0x3f3f3f3f; struct Node{ int x,y; }p[N]; struct Edge{ int u,v,w; }edge[N*40]; int in[N]; int id[N],vis[N],pre[N],n,m; int zhuliu(int rt,int n,int m){ int ret=0; while(1){ for(int i=1;i<=n;++i)in[i]=INF; for(int i=1;i<=m;++i){ if(edge[i].u!=edge[i].v&&edge[i].w<in[edge[i].v]){ pre[edge[i].v]=edge[i].u; in[edge[i].v]=edge[i].w; } } for(int i=1;i<=n;++i) if(i!=rt&&in[i]==INF)return -1; int cnt=0; memset(id,-1,sizeof(id)); memset(vis,-1,sizeof(vis)); in[rt]=0; for(int i=1;i<=n;++i){ ret+=in[i]; int v=i; while(vis[v]!=i&&id[v]==-1&&v!=rt){ vis[v]=i; v=pre[v]; } if(v!=rt&&id[v]==-1){ ++cnt; for(int u=pre[v];u!=v;u=pre[u]) id[u]=cnt; id[v]=cnt; } } if(cnt==0)break; for(int i=1;i<=n;++i) if(id[i]==-1)id[i]=++cnt; for(int i=1;i<=m;++i){ int u=edge[i].u,v=edge[i].v; edge[i].u=id[u]; edge[i].v=id[v]; if(id[u]!=id[v])edge[i].w-=in[v]; } n=cnt; rt=id[rt]; } return ret; } int main() { int T,cas=0; scanf("%d",&T); while(T--){ scanf("%d%d",&n,&m); for(int i=1;i<=m;++i){ scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w); ++edge[i].u,++edge[i].v; } printf("Case #%d: ",++cas); int ans=zhuliu(1,n,m); if(ans==-1)printf("Possums! "); else printf("%d ",ans); } return 0; }