题意:给出一个图,求出次小生成树。。。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <algorithm> 3 #include <cstring> 4 using namespace std; 5 #define maxn 102 6 #define inf (int)(1<<31-1) 7 int s[maxn][maxn],f[maxn][maxn],pos[maxn],lowcost[maxn],closest[maxn]; 8 void init(int n) 9 { 10 for(int i=1;i<=n;i++) 11 for(int j=1;j<=n;j++){ 12 s[i][j]=inf; 13 f[i][j]=-inf; 14 } 15 } 16 int mst(int n) 17 { 18 int Min,k,ans=0; 19 memset(pos,0,sizeof(pos)); 20 pos[1]=1; 21 for(int i=1;i<=n;i++){ 22 lowcost[i]=s[1][i]; 23 closest[i]=1; 24 } 25 lowcost[1]=0; 26 for(int i=1;i<n;i++){ 27 Min=inf; 28 for(int j=1;j<=n;j++) 29 if(lowcost[j]!=0&&Min>lowcost[j]){ 30 Min=lowcost[j]; 31 k=j; 32 } 33 ans+=Min; 34 s[closest[k]][k]=inf; 35 s[k][closest[k]]=inf; 36 for(int j=1;j<=n;j++) 37 if(pos[j]==1){ 38 f[k][j]=max(f[closest[k]][j],lowcost[k]); 39 f[j][k]=f[k][j]; 40 } 41 lowcost[k]=0; 42 pos[k]=1; 43 for(int j=1;j<=n;j++) 44 if(lowcost[j]!=0&&lowcost[j]>s[k][j]){ 45 lowcost[j]=s[k][j]; 46 closest[j]=k; 47 } 48 } 49 return ans; 50 } 51 int deal(int n) 52 { 53 int ans=inf; 54 for(int i=1;i<=n;i++) 55 for(int j=1;j<=n;j++) 56 if(s[i][j]!=inf) 57 ans=min(ans,s[i][j]-f[i][j]); 58 return ans; 59 } 60 int main() 61 { 62 int t; 63 scanf("%d",&t); 64 while(t--){ 65 int n,m; 66 scanf("%d%d",&n,&m); 67 init(n); 68 while(m--){ 69 int a,b,c; 70 scanf("%d%d%d",&a,&b,&c); 71 s[a][b]=c; 72 s[b][a]=c; 73 } 74 int s1=mst(n); 75 int s2=deal(n); 76 printf("%d %d ",s1,s1+s2); 77 } 78 return 0; 79 }