1.题意:存在一个N*M的矩形,代表街区的集合,然后从左上角作为起点,向右下角驶去,分成的每个小矩形就是街区,并且有速度限制,如果街道,即小矩形的边为0的时候不能行驶,现在需要编写一个程序,符合这些限制并且是最短路径。
2.思路:利用Dijkstra算法。每一条边是 "数字"+“空格”+“符号”的形式, 数字表示这条边的限速, 符号表示这条路是单向(还分东西, 南北)的还是双向的。处理完复杂的输出和读取问题之后。
3.感想:题跟前面的思想相似,就是麻烦些
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<utility> using namespace std; typedef pair<int,int>pii; const int INF = 0x7fffffff; const int VN = 445; const int EN = VN*VN/2; struct Edge{ int v, next, w; }E[EN]; int n; int m; int vn; int size; int head[VN]; int d[VN]; void addEdge(int u,int v,int w){ E[size].v=v; E[size].w=w; E[size].next=head[u]; head[u]=size++; } void init(){ vn=(m+1)*(n+1); size=0; memset(head, -1, sizeof(head)); } void Dijkstra(int src){ for(int i=1; i<=vn; ++i)d[i]=INF; d[src]=0; priority_queue<pii,vector<pii>,greater<pii> >q; q.push(make_pair(d[src],src)); while(!q.empty()){ pii x = q.top(); q.pop(); int u=x.second; if(d[u]!=x.first)continue; for(int e=head[u]; e!=-1; e=E[e].next){ int tmp=d[u]+E[e].w; if(d[E[e].v] > tmp){ d[E[e].v] = tmp; q.push(make_pair(tmp,E[e].v)); } } } } int main(){ char str[100]; int u,v,w; while(~scanf("%d%d%*c",&n,&m)&&n+m){ // input init(); for(int i=1; i<=n*2+1; ++i){ gets(str); int len=strlen(str); if(i&1){ for(int j=0,k=1; j<len; j+=4,++k){ u=(m+1)*(i/2)+k; w = str[j]-'0'; if(w==0)continue; if(str[j+2]=='*'){ addEdge(u,u+1,2520/w); addEdge(u+1,u,2520/w); } else if(str[j+2]=='<'){ addEdge(u+1,u,2520/w); } else{ addEdge(u,u+1,2520/w); } } } else{ for(int j=0,k=1; j<len; j+=4,++k){ u = (m+1)*(i/2-1)+k; w = str[j]-'0'; if(w==0) continue; if(str[j+2]=='*'){ addEdge(u, u+m+1, 2520/w); addEdge(u+m+1, u, 2520/w); } else if(str[j+2]=='v'){ addEdge(u, u+m+1, 2520/w); } else if(str[j+2]=='^'){ addEdge(u+m+1, u, 2520/w); } } } } Dijkstra(1); if(d[vn]!=INF) printf("%d blips\n", d[vn]); else puts("Holiday"); } return 0; }