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 }

 

 

posted @ 2012-10-05 15:29  proverbs  阅读(243)  评论(0编辑  收藏  举报