这道题的思路就是求最小生成树。详见AC code 的注释
先贴一个WA的代码,这个代码的bug让我查了两天,最后才茅塞顿开。。。
#include
#include
#include
#define max 0x7fffffff
using namespace std;
struct edge
{
int v1;
int v2;
int w;
}e[6000];
int cmp(const void *a,const void *b)
{
struct edge *aa=(struct edge *)a;
struct edge *bb=(struct edge *)b;
if(aa->w != bb->w)
return aa->w - bb->w;
else
return aa->v1 - bb->v1;
}
int main()
{
int n,q,a,b,map[101][101],vis[101],i,j,k,min;
while(scanf("%d",&n)!=EOF)
{
min=0;
for(i=1;i<=n;i++) vis[i]=i;
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
scanf("%d",&map[i][j]);
}
map[i][i]=max;
}
scanf("%d",&q);
for(i=1;i<=q;i++)
{
scanf("%d%d",&a,&b);
map[a][b]=map[b][a]=0;
vis[b]=vis[a];//连通的两点标记相同,修改数值大的顶点使之与小的顶点相同,bug就在这里
}
for(i=1,k=1;i<=n;i++)
{
for(j=1;j<=i;j++)
{
e[k].v1=i;
e[k].v2=j;
e[k].w=map[i][j];
k++;
}
}
qsort(&e[1],k-1,sizeof(e[1]),cmp);
//j记录生成树中的边数,边数最终要等于n-1
for(i=1,j=q;jvis[e[i].v2] ? vis[e[i].v2] : vis[e[i].v1];
int M=vis[e[i].v1]>vis[e[i].v2] ? vis[e[i].v1] : vis[e[i].v2];
for(int ii=1;ii<=n;ii++)
{
if(vis[ii]==M)
vis[ii]=m;
}
min+=e[i].w;
j++;
}
}
printf("%d\n",min);
}
return 0;
}
AC code(15ms)
#include
#include
#include
#define max 0x7fffffff
using namespace std;
struct edge
{
int v1;
int v2;
int w;
}e[6000];//储存边
int cmp(const void *a,const void *b)
{
struct edge *aa=(struct edge *)a;
struct edge *bb=(struct edge *)b;
if(aa->w != bb->w)
return aa->w - bb->w;
else
return aa->v1 - bb->v1;//当权值相同时按顶点排序
}
int main()
{
int n,q,a,b,map[101][101],vis[101],i,j,k,min;//map记录邻接矩阵,vis为顶点设置标志
while(scanf("%d",&n)!=EOF)
{
min=0;
for(i=1;i<=n;i++) vis[i]=i;//初始化vis,使各个顶点开始时各自属于独立的集合
//输入邻接矩阵
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
scanf("%d",&map[i][j]);
}
map[i][i]=max;//自己到自己的路径修改为max
}
//输入已修好的路径
scanf("%d",&q);
for(i=1;i<=q;i++)
{
scanf("%d%d",&a,&b);
map[a][b]=map[b][a]=0;
//vis[b]=vis[a];
}
//将边的信息存入结构体e,注意只需存下三角形
for(i=1,k=1;i<=n;i++)
{
for(j=1;j<=i;j++)
{
e[k].v1=i;
e[k].v2=j;
e[k].w=map[i][j];
k++;
}
}
//快排,因为从e[1]开始储存,故从e[1]开始排序
qsort(&e[1],k-1,sizeof(e[1]),cmp);
//生成树
for(i=1,j=1;jvis[e[i].v2] ? vis[e[i].v2] : vis[e[i].v1];
int M=vis[e[i].v1]>vis[e[i].v2] ? vis[e[i].v1] : vis[e[i].v2];
for(int ii=1;ii<=n;ii++)
{
if(vis[ii]==M)
vis[ii]=m;
}
min+=e[i].w;
j++;
}
}
printf("%d\n",min);
}
return 0;
}