hdu 2112(最短路+hash+二分)
/* Name: 最短路(dijkstra邻接矩阵)+hash判重并统计顶点数+二分查找返回顶点位置 Copyright: Author: Try_86 Date: 12/04/12 20:57 Description: 注意:起始点和终点不在给出的路线中的情况!!! */ #include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> using namespace std; const int S = 163; const int N = 155; const int M = 12000; const int MAX = 1000000000; char names[N][35], sName[35], eName[35]; int dis[N], sumVs; struct edge { char u[35]; char v[35]; int w; }e[M]; bool vis[N]; int map[N][N]; struct node {//hash表相关数据信息 char str[35]; node *next; node(char *ch, node *p) { strcpy(str, ch); next = p; } }; struct hash { node *link; }hashTable[S]; void initHashTable() {//hash表初始化 for (int i=0; i<S; ++i) hashTable[i].link = NULL; return ; } unsigned int BKDRHash(char *str) {//hash unsigned int seed = 131; unsigned int hash = 0; while (*str) hash = hash * seed + (*str++); return hash & 0x7FFFFFFF; } void insertAndFind(char *str) {//hash表中插入与查找 int k = BKDRHash(str) % S; node *p = hashTable[k].link; while (p) { if (!strcmp(p->str, str)) return ; p = p->next; } node *q = new node(str, NULL); q->next = hashTable[k].link; hashTable[k].link = q; strcpy(names[sumVs++], str); return ; } void del(node *p) {//释放哈希表所占内存 if (!p) return ; del(p->next); delete p; } int cmp(const void *a, const void *b) { return (strcmp((char *)a, (char *)b)); } int binarySearch(char *str) {//二分查找定位顶点位置 int left = 0; int right = sumVs; while (left <= right) { int mid = (left + right) / 2; if (!strcmp(names[mid], str)) return mid; if (strcmp(names[mid], str) > 0) right = mid - 1; else left = mid + 1; } return -1;//起始点或终点不在二分查找表中是返回-1 } void init(int vs) {//邻接矩阵初始化 for (int i=0; i<vs-1; ++i) { map[i][i] = 0; for (int j=i+1; j<vs; ++j) map[i][j] = map[j][i] = MAX; } return ; } void dijkstra(int vs, int s) {//最短路 memset(vis, false, sizeof(vis)); int pos = s; vis[pos] = true; for (int i=0; i<vs; ++i) dis[i] = map[pos][i]; dis[pos] = 0; int minLen; for (int i=1; i<vs; ++i) { pos = s; minLen = MAX; for (int j=0; j<vs; ++j) { if (!vis[j] && minLen>dis[j]) minLen = dis[j], pos = j; } vis[pos] = true; for (int j=0; j<vs; ++j) { int len = dis[pos] + map[pos][j]; if (!vis[j] && dis[j]>len) dis[j] = len; } } return ; } int main() { int n; while (scanf("%d", &n), n!=-1) { scanf ("%s%s", sName, eName); sumVs = 0; initHashTable(); for (int i=0; i<n; ++i) { scanf ("%s%s%d", e[i].u, e[i].v, &e[i].w); insertAndFind(e[i].u); //插入hash表 insertAndFind(e[i].v); //插入hash表 } qsort(names, sumVs, sizeof(names[0]), cmp); init(sumVs); for (int i=0; i<n; ++i) { int u = binarySearch(e[i].u); //对每条线路的起始点和终点返回顶点位置 int v = binarySearch(e[i].v); if (map[u][v] > e[i].w) map[u][v] = map[v][u] = e[i].w;//判重,选最小者 } int s = binarySearch(sName); int t = binarySearch(eName); if (s==-1 || t==-1) {//起点或终点不在二分查找表中 printf ("-1\n"); continue; } dijkstra(sumVs, s); if (dis[t] == MAX) printf ("-1\n"); else printf ("%d\n", dis[t]); for (int i=0; i<S; ++i) del(hashTable[i].link); } return 0; }