题意:
第一行n m代表n个点m条无向边。
接下来m行每行abc,代表ab之间有一条长度为c的无向边。
求:
最小生成树的边权和 次小生成树的边权和
#include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> #include<math.h> #define INF 0x3f3f3f3f using namespace std; int pho[505][505],n,total,dis[505],from[505],dp[505][505]; bool vis[505]; void prim(int pos){ vis[pos]=1; for(int i=1;i<=n;i++){ if(dis[i]>pho[pos][i]){ dis[i]=pho[pos][i]; from[i]=pos; } } int mmin=INF,next=-1; for(int i=1;i<=n;i++){ if(vis[i]==0&&mmin>dis[i]){ mmin=dis[i]; next=i; } } if(next>0){ for(int i=1;i<=n;i++){ if(vis[i]){ dp[i][next]=max(dp[i][from[next]],mmin); } } pho[from[next]][next]=INF; pho[next][from[next]]=INF; total+=mmin; prim(next); } } int main() { int m; scanf("%d%d",&n,&m); memset(pho,0x3f,sizeof(pho)); memset(dis,0x3f,sizeof(dis)); for(int i=0;i<m;i++){ int a,b,c; scanf("%d%d%d",&a,&b,&c); pho[a][b]=c;pho[b][a]=c; } prim(1); printf("Cost: %d ",total); bool ok=0; int tans=INF; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(pho[i][j]!=INF){ ok=1; tans=min(tans,total-max(dp[i][j],dp[j][i])+pho[i][j]); } } } if(ok==0)tans=-1; printf("Cost: %d ",tans); }