Hash 和 Dijkstra 的速度相互制衡,不知道什么时候是最优的 #include<stdio.h> #include <string.h> #include <string> #include <set> #define N 305 #define INF 0x7ffffff using namespace std; int M; int path[N]; bool mark[N]; int h[N]; int map[N][N]; struct { char s[102]; char e[102]; int dis; }t[10000]; int len; int BKDR_hash(char *str) { unsigned int seed=131; unsigned int hash=0; while(*str) { hash=hash*seed+(*str); str++; } hash=hash & 0x7fffffff; return hash; } int hash(char *str) { unsigned int p; int t; p=BKDR_hash(str); t=p%M; while(h[t]!=-1 && h[t]!=p) t=(t+1)%M; h[t]=p; return t; } void Dij(int start) { int i,j,min,k,dis; for (i=0;i<M;i++) { path[i]=map[start][i]; mark[i]=0; } mark[start]=1; for (i=1;i<M;i++) { k=start; min=INF; for (j=0;j<M;j++) { if (!mark[j] && path[j]<min) { min=path[j]; k=j; } } if (min==INF) return ; mark[k]=1; for (j=0;j<M;j++) { dis=map[k][j]+path[k]; if (dis<path[j] && !mark[j]) path[j]=dis; } } } int main () { //freopen("2112.txt","r",stdin); int n,i,j,p1,p2,start,end; char st[102],en[102]; while(scanf("%d",&n),n!=-1) { set<string> se; scanf("%s%s",st,en); memset(h,-1,sizeof(h)); for (i=0;i<n;i++) { scanf("%s%s%d",t[i].s,t[i].e,&t[i].dis); se.insert(t[i].s); se.insert(t[i].e); } if (!strcmp(st,en)) { printf("0/n"); continue; } len=se.size(); M=len*2+1; for (i=0;i<M;i++) { for (j=0;j<M;j++) map[i][j]=INF; } for (i=0;i<n;i++) { p1=hash(t[i].s); p2=hash(t[i].e); if (map[p1][p2]>t[i].dis) map[p1][p2]=map[p2][p1]=t[i].dis; } start=hash(st); end=hash(en); //for (i=0;i<M;i++) { for (j=0;j<M;j++) printf(map[i][j]==INF? " -":"%4d ",map[i][j]); printf("/n");} Dij(start); printf("%d/n",path[end]==INF? -1:path[end]); } }