一个预处理比较累的最短路,要先生成边,编码是16进制,一开始写成10进制一直WA……
/* author:jxy lang:C/C++ university:China,Xidian University **If you need to reprint,please indicate the source** */ #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <queue> #include <vector> #define pp pair<int,int> #define INF 1E9 using namespace std; int ff[65536];//对于首位的存储,便于生成边 int fn[1001];//拉链法解决冲突 int org[1001],vn[1001];//org是前4位的地址代码 vn是边权值 int first[1001]; int next[1000001];//邻接表 可能退化到n^2 int u[1000001];//边的指向 int n,cnt; int turn(char *s)//hash函数 { int h=0,i; for(i=0;i<4;i++) { h*=16; if(s[i]>'9')h+=s[i]-'A'+10; else h+=s[i]-'0'; } return h; } int d[1002]; int dijkstra(int v) { priority_queue<pp,vector<pp>,greater<pp> > q; memset(d,127,sizeof(d)); d[v]=0; q.push(make_pair(d[v],v)); pp now; int x,i; while(!q.empty()) { now=q.top();q.pop(); x=now.second; if(vn[x]==-1)continue; for(i=first[x];i!=-1;i=next[i]) { if(d[u[i]]<=d[x]+vn[x])continue; d[u[i]]=d[x]+vn[x]; q.push(make_pair(d[u[i]],u[i])); } vn[x]=-1; } // cout<<d[1001]<<endl; return d[n-1]==d[1001]?-1:d[n-1]; } char s[100]; int main() { int i,t,tt,hf,hl; while(~scanf("%d",&n)&&n) { memset(ff,-1,sizeof(ff)); memset(fn,-1,sizeof(fn)); memset(first,-1,sizeof(first)); memset(next,-1,sizeof(next)); cnt=0; for(i=0;i<n;i++) { scanf("%d %s",&t,s); hf=turn(s); hl=turn(s+strlen(s)-4); if(ff[hf]!=-1) fn[i]=ff[hf]; ff[hf]=i; org[i]=hl; vn[i]=t; } for(i=0;i<n;i++) { if(ff[org[i]]==-1)continue; tt=ff[org[i]]; while(tt!=-1) { if(first[i]!=-1) next[cnt]=first[i]; u[cnt]=tt; first[i]=cnt++; tt=fn[tt]; } } //cout<<"ok"<<endl; printf("%d\n",dijkstra(0)); } }