UVA-10600 ACM Contest and Blackout
阿新 • • 發佈:2018-11-02
次小生成樹模板題
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<queue> using namespace std; typedef long long ll; const int N=100+10; const int INF=0x7f7f7f7f; bool vis[N]; int lowc[N],pre[N]; int Max[N][N],cost[N][N]; bool used[N][N]; int Prim(int n) { int ans=0; memset(vis,false,sizeof(vis)); memset(Max,0,sizeof(Max)); memset(used,false,sizeof(used)); pre[1]=-1; vis[1]=true; for(int i=2;i<=n;i++) { lowc[i]=cost[1][i]; pre[i]=1; } for(int i=2;i<=n;i++) { int minc=INF; int p=-1; for(int j=1;j<=n;j++) if(!vis[j]&&minc>lowc[j]) { minc=lowc[j]; p=j; } if(p==-1) return -1; ans+=minc; vis[p]=true; used[pre[p]][p]=used[p][pre[p]]=true; for(int j=1;j<=n;j++) { if(vis[j]&&j!=p) Max[p][j]=Max[j][p]=max(Max[pre[p]][j],minc); if(!vis[j]&&lowc[j]>cost[p][j]) { lowc[j]=cost[p][j]; pre[j]=p; } } } return ans; } void solve(int n) { int ans=Prim(n); int ans2=INF; for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) if(!used[i][j]) ans2=min(ans2,ans+cost[i][j]-Max[i][j]); printf("%d %d\n",ans,ans2); } int main() { int T; int n,m; int a,b,c; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) cost[i][j]=INF; for(int i=0;i<m;i++) { scanf("%d%d%d",&a,&b,&c); cost[a][b]=cost[b][a]=c; } solve(n); } return 0; }