#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
const int inf=0x3f3f3f3f;
using namespace std;
int map[110][110];
int pre[110];
bool use[110][110];
int maxcost[110][110];
int dis[110];
bool vis[110];
int n,m;
int prim()
{
int ans=0;
memset(use,0,sizeof(use));
memset(maxcost,0,sizeof(maxcost));
for(int i=1;i<=n;++i)
{
dis[i]=map[1][i];
pre[i]=1;
vis[i]=0;
}
vis[1]=1; dis[1]=0;
for(int i=1;i<n;++i)
{
int pos=-1, ma=inf;
for(int j=1;j<=n;++j)
{
if(!vis[j]&&ma>dis[j])
{
ma=dis[j]; pos=j;
}
}
if(pos==-1) break;
ans+=ma; vis[pos]=1;
use[pos][pre[pos]]=use[pre[pos]][pos]=1;
for(int j=1;j<=n;++j)
{
if(vis[j]&&j!=pos) maxcost[pos][j]=maxcost[j][pos]=max(maxcost[j][pre[pos]],dis[pos]);
if(!vis[j]&&dis[j]>map[pos][j]) {dis[j]=map[pos][j]; pre[j]=pos; }
}
}
return ans;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)
{
for(int j=1;j<=n;++j)
{
map[i][j]=inf;
if(i==j) map[i][j]=0;
}
}
while(m--)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
if(map[a][b]>c) map[a][b]=map[b][a]=c;
}
int ans=prim();
int next=inf;
for(int i=1;i<=n;++i)
{
for(int j=1;j<=n;++j)
{
if(i==j) continue;
if(use[i][j]) continue;
if(map[i][j]==inf) continue;
next=min(next,ans+map[i][j]-maxcost[i][j]);
}
}
printf("%d %d\n",ans,next);
}
return 0;
}
次小生成树
最新推荐文章于 2019-10-31 21:32:25 发布