The output is one integer per line for each data set: the minimum cost in aacms per month to maintain a road system that connect all the villages. Caution: A brute force solution that examines every possible set of roads will not finish within the one minute time limit.
30
//hdu-1301-Jungle Roads(克鲁斯卡尔)
//题目大意:给出个村庄之间的道路及其维修费;从中选取一些路使道路的维修费最小且保证各村庄
//之间道路畅通;
//解题思路:
//本题最核心的还是构图,由于输入的村庄用字母代替这就需要在构图中将字母替换成数字依次给每个村庄编号;
//需要注意的由于输入的有字符型数据,这就要加一些 getchar()来吸收掉中间的换行空格啥的;
//初始化 per[n] 数组一定要注意,把所有村庄都初始化就行啦;
//具体如下:
#include
#include
#include
using namespace std;
int per[30];
int n,m;
struct fun{ //定义结构体数组road[100],用来存放起点、终点和距离
int s;
int e;
int p;
}road[100];
int cmp(fun x,fun y)
{
return x.p < y.p;
}
void init() //初始化 per 数组 ;注意初始完 n个村庄即可;
{
int d;
for(d=1;d < = n;d++)
per[d]=d;
}
int find(int x)
{
int r=x;
while(r!=per[r])
r=per[r];
return r;
}
bool link(int x,int y)
{
int fx=find(x),fy=find(y);
if(fx!=fy){
per[fx]=fy;
return true;
}
return false;
}
int main()
{
int j,k,l,sum,i,cnt,a1,a2;
char str1,str2;
while(scanf("%d",&n)&&(n!=0))
{
getchar();
memset(road,0,sizeof(road));
memset(per,0,sizeof(per));
init();
for(i=1,cnt=1;i < n;i++) //输入数据,并构图;
{
scanf("%c%d",&str1,&m);
for(j=1;j<=m;j++)
{
getchar();
scanf("%c%d",&str2,&l);
road[cnt].s=str1-'A'+1; //将字母编号转化为数字编号并存入结构体数组中
road[cnt].e=str2-'A'+1;
road[cnt].p=l;
cnt++;
}
getchar();
} //构图完成,剩下的就是克鲁斯卡尔啦;
sort(road,road+cnt,cmp);
sum=0;
for(j=1;j<=cnt;j++)
{
if(link(road[j].s,road[j].e))
sum+=road[j].p;
}
printf("%d\n",sum);
}
return 0;
}
//hdu-1301(普里姆算法)
//本题用普里姆算法求最小生成树直接用普里姆的思想构造函数即可;
//需要注意的是本题再输入数据的是时候要先对 map[1000][1000]中的前 n*n
//个元素初始化为 一个与 min相同或大于它的数;例如,0xfffffff即可;
//(n是结点的个数,由于需要在 n*n 大小的矩阵中构图,所以初始化 n*n 就行);
//为什么要对 map数组初始化呢?一是由于在prim函数中 map要对s[1000]数组赋初值;如果不对map初始化;
//那么,s[]数组中没有数据的就一直为零,与下面的 min比较时,min是永远大于它们的;这样得到的min就一直为零
//最终导致sum为零;还有,不对map按上述初始化,在更新时候也无法完成 ;
#include
#include
#define N 0xfffff
int map[1000][1000];
int n,m,sum,cnt;
void input()
{
char c1,c2;
int i,j,x,y,price;
cnt=0;
for(i=1;i<=n;i++) //对 map数组初始化为 N ;
{
for(j=1;j<=n;j++)
map[i][j]=N;
}
for(i=1;is[j])
{
min=s[j]; //寻找当前最小权值;
k=j;
}
vis[k]=1; //标记顶点k,表示k已连上树;
sum+=min; //将当前最小权值累加到sum中;
for(a=1;a<=n;a++)
{
if(!vis[a]&&s[a]>map[k][a]) //标记当前最小权值的顶点后,更新s[] 数组中的权值 ;
s[a]=map[k][a];
}
}
printf("%d\n",sum);
}
int main()
{
char c1,c2;
int i,j,x,y,price;
while(scanf("%d",&n)&&(n!=0))
{
getchar();
input();
prim();
}
return 0;
}