完整代码
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
typedef long long LL;
const int N = 50, P = 131;
LL ha[N]; //ha[i]表示下标i的字符串的哈希值
int p[N]; //用于搜索结点是否联通
char place[N][21]; //城市的名称对应其下标存在place中,如place[1]="Xiamen"表示"Xiamen"对应的编号是1
int n,m; //n表示城市的数目,m表示路径的数目
struct Road {//Road结构体存储每条路径的信息
int a, b, len;
//a,b分别表示城市编号 len表示城市间距离
bool operator < (const Road &W) const
{
return len < W.len;
}
}roads[N];
LL hash_num(char s[])//求字符串s的哈希值
{
LL h[20]; //h[i]表示长度为i的部分的串的hash值
h[0] = 0; //初始化
int l = strlen(s);//l为s的长度
for(int i = 0; i < l; i ++ )
h[ i+1 ] = h[i] * P + s[i];//hash具体函数
return h[l];//返回串s的hash值
}
//find函数用来查找
int find(char s[])
{
int l = strlen(s);//l为串s的长度
LL hs = hash_num(s);//hs为串s的hash值
for(int i = 0; i < n; i ++)
在所有已经存储过的串里查找有无hash值相等的,若有,输出其下标
if(ha[i] == hs)return i;
//由于id是以递增的方式取的,那么到ha[i]为0后,后面的ha值全为0
else if(ha[i] == 0)return -1; //如果没有,返回-1
return -1;
}
//search函数用于搜索结点x所在联通树终点
int search(int x)
{
if(p[x] != x)p[x] = search(p[x]);//x不是新的结点,往下找
return p[x];
}
int kruskal()
{
int cnt = 0; //已经存储过的边
int res = 0; //最小生成树的总权值
for(int i = 0; cnt != n - 1 && i < m; i ++ )
{
//边的信息的取出
int a = roads[i].a;
int b = roads[i].b;
int w = roads[i].len;
if( search(a) != search(b) )//两点不联通
{
res += w;//边权存入
cnt ++; //边数++
p[search(a)] = p[search(b)];//连接两个结点
printf("第%d条线路为%s <-> %s, 路径长为%d\n",cnt,place[a],place[b],w);
}
}
return res;//返回总权值
}
int main()
{
memset(ha, 0, sizeof ha);//初始化
scanf("%d%d", &n,&m);
int id = 0; //id初始化
for(int i = 0; i < n; i ++ )//p数组初始化
p[i] = i;
//创建所有路径信息
for(int i = 0; i < m; i ++ )
{
printf("请输入两个地区的信息:");
char origin[21],terminal[21];
//origin和terminal分别为两个城市名
int w;//边权
scanf("%s%s%d", origin, terminal, &w);
roads[i].len = w;
//若find值为-1,表示地点信息未创建,则创建即可。
if( find(origin) == -1)
{
roads[i].a = id; //赋值给其一个id
ha[id] = hash_num(origin);//求出其hash值
strcpy(place[id], origin);//origin复制给place[i]
id ++;
}
else roads[i].a = find(origin);//已经有,直接把其find值存入
//同理
if( find(terminal) == -1)
{
roads[i].b = id;
ha[id] = hash_num(terminal);
strcpy(place[id], terminal);
id ++;
}
else roads[i].b = find(terminal);
}
sort(roads,roads + m);
int res = kruskal();
printf("总路径长为%d\n",res);
return 0;
}
测试数据
4 5
Xiamen Shanghai 600
Shanghai Hefei 1000
Hefei Beijing 900
Beijing Xiamen 1500
Beijing Shanghai 1300
输出