3 0 990 692 990 0 179 692 179 0 1 1 2
179
还是修路问题。这道题两种解法,一种是贪心+并查集。
一种就是最小生成树了。今天刚学的。
所以用了它做。发现自己无法用语言来描绘这个算法。。
贴下代码吧。
#include <stdio.h>
#include <algorithm>
using namespace std;
#include <string.h>
#define inf 0x6ffffff
int vis[102];//用来标记是否被用过
int map[102][102];
int dis[102];
int n,sum;
void prim()
{
int i,j,k,min;
for(i=1;i<=n;i++)
dis[i]=map[1][i];
vis[1]=1;
for(i=1;i<=n;i++)
{
min=inf;
for(j=1;j<=n;j++)
{
if(vis[j]==0&&dis[j]<min)
{
min=dis[j];
k=j;
}
}
if(min==inf)
break;
vis[k]=1;
sum+=min;
for(j=1;j<=n;j++)
{
if(vis[j]==0 &&dis[j]>map[k][j])
dis[j]=map[k][j];
}
}
}
int main()
{
int ll,i,j,str,end,m;
while(scanf("%d",&n)!=EOF)
{
memset(vis,0,sizeof(vis));
memset(dis,0,sizeof(dis));
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
map[i][j]=inf;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
scanf("%d",&ll);
if(map[i][j]>ll)
map[i][j]=map[j][i]=ll;
}
scanf("%d",&m);
for(i=1;i<=m;i++)
{
scanf("%d%d",&str,&end);
map[str][end]=map[end][str]=0; //这里必须是双向的。不能写成 map[str][end]=0。因为这里WA了两次
}
sum=0;
prim();
printf("%d\n",sum);
}
return 0;
}
原文地址:http://blog.csdn.net/sky_miange/article/details/43410101