題目大意:給你一張圖,求它的最小生成樹和最大生成樹的的總費用/2;
題目解析: 用prime算法即可,求最小生成樹的時候,隻要每次取出長度目前長度最小的那條邊,并且維護dist[]就可以了,因為是樹狀結構,肯定不會有環,最大生成樹也是類似;
AC代碼:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
const int inf=0x3fffffff;
int graph1[110][110],graph2[110][110],dist[110],n;
bool vis[110];
int min_prime()
{
int sum=0,i,j,k,temp;
memset(vis,0,sizeof(vis));
vis[0]=1;
for(i=1;i<=n;i++)
{
dist[i]=graph1[0][i];
}
for(k=1;k<=n;k++)
{
temp=inf;
j=-1;
for(i=1;i<=n;i++)
{
if(!vis[i]&&dist[i]<temp)
{
temp=dist[i];
j=i;
}
}
if(j==-1)
return sum;
sum+=temp;
vis[j]=1;
for(i=1;i<=n;i++)
{
if(!vis[i]&&dist[i]>graph1[j][i])
{
dist[i]=graph1[j][i];
}
}
}
return sum;
}
int max_prime()
{
int sum=0,i,j,k,temp;
memset(vis,0,sizeof(vis));
vis[0]=1;
for(i=1;i<=n;i++)
{
dist[i]=graph2[0][i];
}
for(k=1;k<=n;k++)
{
temp=0;
j=-1;
for(i=1;i<=n;i++)
{
if(!vis[i]&&dist[i]>temp)
{
temp=dist[i];
j=i;
}
}
if(j==-1)
return sum;
sum+=temp;
vis[j]=1;
for(i=1;i<=n;i++)
{
if(!vis[i]&&dist[i]<graph2[j][i])
{
dist[i]=graph2[j][i];
}
}
}
return sum;
}
int main()
{
int cas,c,u,v,w,i,j;
scanf("%d",&cas);
for(c=1;c<=cas;c++)
{
memset(graph2,0,sizeof(graph1));
for(i=0;i<110;i++)
for(j=0;j<110;j++)
graph1[i][j]=inf;
scanf("%d",&n);
while(scanf("%d%d%d",&u,&v,&w)&&(u+v+w)!=0)
{
graph1[v][u]=graph1[u][v]=min(w,graph1[u][v]);
graph2[v][u]=graph2[u][v]=max(w,graph2[u][v]);
}
int min_cost=min_prime();
int max_cost=max_prime();
if((max_cost+min_cost)%2==1)
printf("Case %d: %d/2\n",c,max_cost+min_cost);
else
printf("Case %d: %d\n",c,(max_cost+min_cost)/2);
}
return 0;
}