题目:Jungle Roads-----------POJ - 1251
题意:
——n个村庄,村庄用大写字母A ~ Z表示。
给出n-1行数据,
每行按字母顺序排列的村庄标签开始。最后一个村庄没有排队。一个村庄的每一行都以村庄标签开始,然后是从这个村庄到后面字母表中带有标签的村庄的道路编号k。如果k大于0,则该线将继续显示k条道路的数据。每条道路的数据是道路另一端的村庄标签,然后是该道路每月维护成本。维护成本将是小于100的正整数。
——求使n个村庄连通的最小费用。
注意:保证原始道路可是n个村庄都连续。
解题思路:(最小生成树模板)
——对字符和空格的处理,每一个字符都看成一个字符串这样就不用管理空格和回车了。
——基本和单源最短路模板类似。
代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
int e[220][220],dis[220],book[220],n;
void init()
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
if(i==j) e[i][j]=0;
else e[i][j]=INF;
}
}
void Prim()
//最小生成树从任何点开始建都不会影响最终的结果
{
int i,j,u,v,mind,count=0,sum=0;
memset(book,0,sizeof(book));
for(i=1;i<=n;i++)
dis[i]=e[1][i];
book[1]=1; //把1加入到树中
//count++;
//每一次循环都加一个点,最多再加n-1个点
for(i=1;i<=n-1;i++)
{
mind=INF;u=-1;
for(j=1;j<=n;j++)
{
if(!book[j]&&mind>dis[j])
{
mind=dis[j];
u=j;
}
}
if(u==-1) break;
book[u]=1;
sum+=dis[u];
//count++;
//if(count==n) break;
for(v=1;v<=n;v++)
{
if(!book[v]||e[u][v]<INF)
{
if(dis[v]>e[u][v])
dis[v]=e[u][v];
}
}
}
printf("%d\n",sum);
}
int main()
{
while(~scanf("%d",&n)&&n)
{
init();
char a[5],b[5];
int i,j,m,w;
for(i=1;i<=n-1;i++)
{
scanf("%s %d",a,&m);
for(j=1;j<=m;j++)
{
scanf("%s %d",b,&w);
}
}
Prim();
}
return 0;
}