/* 题目其实很简单,只是题目太长了,看懂有点不容易,最郁闷的是以开始就看懂了的, 只是2520/8 = 290 了,结果导致自己看懂的想法彻底崩溃,于是就在纠结中挣扎,痛苦ing。。 没想到这么弱智的毛病也犯 题目大致意思从起点到终点找一条花费时间最少的路,并输出(blips其实就是时间) 每条路的距离是2520 (是1 到 9的最小公倍数 可以不管的), 给你两点之间最大速度 P 两点的时间 t = 2520 / p;注意 p = 0的是,两点为断路,接下来就是构图共有 v = n * ( m + 1) + m 个点 */ #include <iostream> #include <cstdio> #include <queue> #include <cstring> using namespace std; const int INF = 0x3fffffff; const int N = 1005; int cost[N][N]; int dis[N]; bool hash[N]; struct node { int dis; int num; friend bool operator < (node a, node b) { return a.dis > b.dis; } }; void BFS(int end) { memset(hash, false, sizeof(hash)); node P, F; priority_queue <node> Q; for(int i = 1; i <= end; i++) { dis[i] = cost[0][i]; if(dis[i] != INF) { P.num = i; P.dis = dis[i]; Q.push(P); } } hash[0] = true; while(!Q.empty()) { F = Q.top(); Q.pop(); if(hash[end]) break; hash[F.num] = true; for(int i = 1; i <= end; i++) { if(!hash[i] && dis[i] > F.dis + cost[F.num][i] && cost[F.num][i] != INF) { dis[i] = F.dis + cost[F.num][i]; P.num = i; P.dis = dis[i]; Q.push(P); } } } } inline int direction_w_e(char s[]) { if(s[0] == '*') return 2; if(s[0] == '>') return 1; if(s[0] == '<') return -1; } inline int direction_n_s(char s[]) { if(s[0] == '*') return 2; if(s[0] == '^') return 1; if(s[0] == 'v') return -1; } inline void Int() { for(int i = 0 ;i < N; i++) for(int j = 0; j < N; j++) { if(i == j) cost[i][j] = 0; else cost[i][j] = INF; } } int main() { int n, m; while(scanf("%d %d", &n, &m) != EOF ) { if(n == 0 && m == 0 ) break; int sp, p; char s[2]; int dir; int M = m + 1; Int(); //以下是构图很麻烦,用邻接表很应该简单点的,要学习下。。 for(int i = 0; i <= n; i++) { if(i == 0) { for(int j = 1; j <= m; j++) { scanf("%d %s", &p, s); if(p == 0) { cost[j - 1][j] = cost[j][j - 1] = INF; continue; } sp = 2520 / p; dir = direction_w_e(s); if(dir == 2) cost[j - 1][j] = cost[j][j - 1] = sp; if(dir == -1) cost[j][j - 1] = sp; if(dir == 1) cost[j - 1][j] = sp; } } else { for(int j = 0; j <= m; j++) { scanf("%d %s", &p, s); if(p == 0) { cost[(i - 1) * M + j][ M * i + j] = cost[M * i + j][M * (i - 1) + j] = INF; continue; } sp = 2520 / p; dir = direction_n_s(s); if(dir == 2) cost[(i - 1) * M + j][ M * i + j] = cost[M * i + j][M * (i - 1) + j] = sp; if(dir == -1) cost[(i - 1) * M + j][ M * i + j] = sp; if(dir == 1) cost[M * i + j][M * (i - 1) + j] = sp; } for(int j = 1; j <= m; j++) { scanf("%d %s", &p, s); if(p == 0) { cost[M * i + j][M * i + j -1] = cost[M * i + j -1][M * i + j] = INF; continue; } sp = 2520 / p; dir = direction_w_e(s); if(dir == 2) cost[M * i + j][M * i + j -1] = cost[M * i + j -1][M * i + j] = sp; if(dir == -1) cost[M * i + j][M * i + j -1] = sp; if(dir == 1) cost[M * i + j -1][M * i + j] = sp; if(sp == 0) cost[M * i + j][M * i + j -1] = cost[M * i + j -1][M * i + j] = INF; } } } int end = n * M + m; BFS(end); if(dis[end] != INF) printf("%d blips/n", dis[end]); else printf("Holiday/n"); } } /* #include <iostream> #include <cstdio> #include <algorithm> #include <memory.h> #include <cmath> #include <bitset> #include <queue> #include <vector> using namespace std; const int border = (1<<20)-1;const int maxsize = 37;const int maxn = 1105;const int inf = 1000000000;#define clr(x,y) memset(x,y,sizeof(x))#define add(x) x=((x+1)&border)#define in(x) scanf("%d",&x)#define out(x) printf("%d/n",x)#define min(m,v) (m)<(v)?(m):(v)#define max(m,v) (m)>(v)?(m):(v)#define abs(x) ((x)>0?(x):-(x))#define len 2520#define set_node(no,a,b) {no.u=a;no.val=b;}typedef struct{ int v,next; int val;}edge;typedef struct{ int u; int val;}node;bool operator < (const node& a,const node& b){ return a.val > b.val;}edge edge[maxn*maxn];int n,m,start,end,index;int dist[maxn],net[maxn];bool visit[maxn];void add_edge(const int& u,const int& v,const int& sp){ edge[index].v = v; edge[index].next = net[u]; edge[index].val = sp; net[u] = index++;}void add_input(const int& u,const int& v,const int& sp,const char& c){ if(c=='*') { add_edge(u,v,sp); add_edge(v,u,sp); return ; } if( c == '>' || c=='v') add_edge(u,v,sp); else add_edge(v,u,sp);}int init(){ index = 0; clr(net,-1); clr(visit,0); clr(dist,127); return 0;}int input(){ int i,j,u,v,tmp,sp; char ch; for(i = 0; i < n-1; ++i) { for(j = 0; j < m-1; ++j) { scanf("%d %c",&sp,&ch); if(sp == 0) continue; u = i*m + j; v = u + 1; add_input(u,v,sp,ch); } for(j = 0; j < m; ++j) { scanf("%d %c",&sp,&ch); if(sp == 0) continue; u = i*m + j; v = (i+1)*m + j; add_input(u,v,sp,ch); } } for(j = 0; j < m-1; ++j) { scanf("%d %c",&sp,&ch); u = (n-1)*m + j; v = u + 1; if(sp == 0) continue; add_input(u,v,sp,ch); } return 0;}int dij(){ int i,j,u,tmp,mark,mmin,v; int n = n*m; priority_queue<node> que; node node,t_node; while(!que.empty()) que.pop(); set_node(t_node,0,0); que.push(t_node); dist[0] = 0; clr(visit,0); while(!que.empty()) { node = que.top(); que.pop(); u = node.u; if(visit[node.u]) continue; if(u == n-1) return node.val; visit[u] = true; for(i = net[u]; i != -1; i = edge[i].next) { v = edge[i].v; if(visit[v]) continue; tmp = dist[u] + len/edge[i].val; if(dist[v] > tmp) { dist[v] = tmp; set_node(t_node,v,tmp); que.push(t_node); } } } return -1;}int work(){ int i,j,ans; ans = dij(); if(ans == -1) printf("holiday/n"); else printf("%d blips/n",ans); return 0;}int main(){ while(scanf("%d%d",&n,&m)) { if(!n && !m) break; ++n,++m; init(); input(); work(); } return 0;}o(n^2): #include <iostream>#include <cstdio>#include <algorithm>#include <memory.h>#include <cmath>#include <bitset>#include <queue>#include <vector>using namespace std;const int border = (1<<20)-1;const int maxsize = 37;const int maxn = 1105;const int inf = 1000000000;#define clr(x,y) memset(x,y,sizeof(x))#define add(x) x=((x+1)&border)#define in(x) scanf("%d",&x)#define out(x) printf("%d/n",x)#define min(m,v) (m)<(v)?(m):(v)#define max(m,v) (m)>(v)?(m):(v)#define abs(x) ((x)>0?(x):-(x))#define len 2520typedef struct{ int v,next; int val;}edge;typedef struct{ int u; int val;}node;bool operator < (const node& a,const node& b){ return a.val > b.val;}edge edge[maxn*maxn];int n,m,start,end,index;int dist[maxn],net[maxn];bool visit[maxn];void add_edge(const int& u,const int& v,const int& sp){ edge[index].v = v; edge[index].next = net[u]; edge[index].val = sp; net[u] = index++;}void add_input(const int& u,const int& v,const int& sp,const char& c){ if(c=='*') { add_edge(u,v,sp); add_edge(v,u,sp); return ; } if( c == '>' || c=='v') add_edge(u,v,sp); else add_edge(v,u,sp);}int init(){ index = 0; clr(net,-1); clr(visit,0); clr(dist,127); return 0;}int input(){ int i,j,u,v,tmp,sp; char ch; for(i = 0; i < n-1; ++i) { for(j = 0; j < m-1; ++j) { //cin>>sp>>ch; scanf("%d %c",&sp,&ch); if(sp == 0) continue; u = i*m + j; v = u + 1; add_input(u,v,sp,ch); } for(j = 0; j < m; ++j) { //cin>>sp>>ch; scanf("%d %c",&sp,&ch); if(sp == 0) continue; u = i*m + j; v = (i+1)*m + j; add_input(u,v,sp,ch); } } for(j = 0; j < m-1; ++j) { //cin>>sp>>ch; scanf("%d %c",&sp,&ch); u = (n-1)*m + j; v = u + 1; if(sp == 0) continue; add_input(u,v,sp,ch); } return 0;}int dij(){ int i,j,tmp,mark,mmin,v; int n = n*m; dist[0] = 0; clr(visit,0); for(i = 0; i < n; ++i) { mmin = inf; for(j = 0; j < n; ++j) if(!visit[j] && mmin > dist[j]) { mmin = dist[j]; mark = j; } visit[mark] = true; for(j = net[mark]; j != -1; j = edge[j].next) { tmp = len/edge[j].val; v = edge[j].v; if(!visit[v] && dist[v] > tmp + mmin) { dist[v] = tmp + mmin; } } } if(dist[n-1] > inf) return -1; return dist[n-1];}int work(){ int i,j,ans; ans = dij(); if(ans == -1) printf("holiday/n"); else printf("%d blips/n",ans); return 0;}int main(){ while(scanf("%d%d",&n,&m)) { if(!n && !m) break; ++n,++m; init(); input(); work(); } return 0;} */