TYVJ 1993 HASH+最短路
考试的时候偷懒,写的map,结果被卡了。。。20分。。我这弱菜、、
其实此题很水。。。
思路:
明显的最短路,就是写hash呗。。
表示从来没写过hash,一直用map水的。。
头一次写hash,还1A了~嘿嘿,细心点就好
PS:我的hash函数不取摸是完美的。
View Code
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <string> 5 #include <algorithm> 6 #include <iostream> 7 8 #define MOD 999991 9 #define N 50500 10 #define M 3000000 11 12 bool fg; 13 using namespace std; 14 15 struct HEAP 16 { 17 int x,d; 18 }hp[N]; 19 20 int fac[12],hto[N],hnext[N],hhead[1000000],next[M],head[N],to[M],len[M],hcnt,cnt; 21 int hash[N],n,lcp[12],dis[N],size; 22 char tel[N][12],sst[12],stmp; 23 24 inline bool cmp(const HEAP &a,const HEAP &b) 25 { 26 return a.d>b.d; 27 } 28 29 void prev()//check 30 { 31 fac[1]=1; 32 for(int i=2;i<=10;i++) fac[i]=fac[i-1]*10; 33 } 34 35 void addhash(int u,int v) 36 { 37 hto[hcnt]=v; hnext[hcnt]=hhead[u]; hhead[u]=hcnt++; 38 } 39 40 void add(int u,int v,int w) 41 { 42 to[cnt]=v; len[cnt]=w; next[cnt]=head[u]; head[u]=cnt++; 43 } 44 45 void close(int x) 46 { 47 __int64 tmp=0,sk; 48 for(int i=1;i<=10;i++) 49 { 50 sk=tel[x][i]-'0'; 51 tmp+=sk*fac[i]; 52 } 53 hash[x]=tmp%MOD; 54 addhash(hash[x],x); 55 } 56 57 void cpy(int x) 58 { 59 for(int i=1;i<=11;i++) sst[i]=tel[x][i]; 60 } 61 62 int gethash() 63 { 64 __int64 rt=0,tmp; 65 for(int i=1;i<=10;i++) 66 { 67 tmp=(sst[i]-'0'); 68 rt+=tmp*fac[i]; 69 } 70 rt%=MOD; 71 for(int i=hhead[rt];~i;i=hnext[i]) 72 if(strcmp(&sst[1],&tel[hto[i]][1])==0) 73 return hto[i]; 74 return 0; 75 } 76 77 void create() 78 { 79 for(int i=1;i<=n;i++) 80 { 81 cpy(i); 82 for(int j=1;j<=10;j++) 83 for(int k=j+1;k<=10;k++) 84 if(sst[j]!=sst[k]) 85 { 86 swap(sst[j],sst[k]); 87 if(i==1&&j==4&&k==10) fg=true; 88 int tmp=gethash(); 89 if(tmp) 90 { 91 add(i,tmp,lcp[j-1]); 92 add(tmp,i,lcp[j-1]); 93 } 94 swap(sst[j],sst[k]); 95 } 96 for(int j=1;j<=10;j++) 97 for(int k=0;k<=9;k++) 98 if(sst[j]!=k+'0') 99 { 100 stmp=sst[j]; 101 sst[j]=k+'0'; 102 int tmp=gethash(); 103 if(tmp) 104 { 105 add(i,tmp,lcp[j-1]); 106 add(tmp,i,lcp[j-1]); 107 } 108 sst[j]=stmp; 109 } 110 } 111 } 112 113 void read() 114 { 115 memset(head,-1,sizeof head);cnt=1; 116 memset(hhead,-1,sizeof hhead);hcnt=1; 117 scanf("%d",&n); 118 for(int i=0;i<10;i++) scanf("%d",&lcp[i]); 119 for(int i=1;i<=n;i++) 120 { 121 scanf("%s",&tel[i][1]); 122 close(i); 123 } 124 } 125 126 void dijkstra() 127 { 128 memset(dis,0x3f,sizeof dis); 129 size=1; 130 hp[1].x=1; hp[1].d=0; dis[1]=0; 131 while(size) 132 { 133 int sta=hp[1].x; 134 int k=hp[1].d; 135 pop_heap(hp+1,hp+1+size,cmp); 136 size--; 137 if(dis[sta]<k) continue; 138 for(int i=head[sta];~i;i=next[i]) 139 if(dis[to[i]]>dis[sta]+len[i]) 140 { 141 dis[to[i]]=dis[sta]+len[i]; 142 size++; 143 hp[size].x=to[i]; hp[size].d=dis[to[i]]; 144 push_heap(hp+1,hp+1+size,cmp); 145 } 146 } 147 if(dis[n]==0x3f3f3f3f) dis[n]=-1; 148 cout<<dis[n]<<endl; 149 } 150 151 int main() 152 { 153 prev(); 154 read(); 155 create(); 156 dijkstra(); 157 return 0; 158 }
没有人能阻止我前进的步伐,除了我自己!