-
总时间限制:
- 1000ms 内存限制:
- 65535kB
-
描述
-
“红楼飞雪,一时英杰……”耳边传来了那熟悉的歌声。而这,只怕是我最后一次听到这个声音了。
想当年,我们曾经怀着豪情壮志,许下心愿,走过静园,走过一体,走过未名湖畔的每个角落。
想当年,我们也曾慷慨高歌,瞻仰民主与科学,瞻仰博雅塔顶,那百年之前的遗韵。
没错,我爱北大,我爱这个校园。
然而,从当我们穿上学位服的那一刻起,这个校园,就再也不属于我。它只属于往事,属于我的回忆。
没错,这,是我在北大的最后一日。此时,此景,此生,此世,将刻骨难忘。
再也没有了图书馆自习的各种纷纭,再也没有了运动场上的挥汗如雨,有的,只是心中永远的不舍,与牵挂。
夜,已深。人,却不愿离去。天边有一颗流星划过,是那般静,宁谧。
忍不住不回头,我的眼边,有泪光,划过。
这时候,突然有一位路人甲从你身旁出现,问你:从XX到XX怎么走?
索性,就让我再爱你一次。因为,北大永远在你心中。北大的地图,永远在你的心中。
轻手挥扬,不带走一分云彩。
输入
-
输入分为三个部分。
第一个部分有P+1行,第一行为一个整数P,之后的P行表示北大的地点。
第二个部分有Q+1行,第一行为一个整数Q,之后的Q行每行分别为两个字符串与一个整数,表示这两点有直线的道路,并显示二者之间的矩离(单位为米)。
第三个部分有R+1行,第一行为一个整数R,之后的R行每行为两个字符串,表示需要求的路线。
p<30,Q<50,R<20
输出
- 输出有R行,分别表示每个路线最短的走法。其中两个点之间,用->(矩离)->相隔 样例输入
-
6 XueYiShiTang CanYinZhongXin XueWuShiTang XueYiXiaoBaiFang BaiNianJiangTang GongHangQuKuanJi 6 XueYiShiTang CanYinZhongXin 80 XueWuShiTang CanYinZhongXin 40 XueYiShiTang XueYiXiaoBaiFang 35 XueYiXiaoBaiFang XueWuShiTang 85 CanYinZhongXin GongHangQuKuanJi 60 GongHangQuKuanJi BaiNianJiangTang 35 1 XueYiXiaoBaiFang BaiNianJiangTang
样例输出
-
XueYiXiaoBaiFang->(35)->XueYiShiTang->(80)->CanYinZhongXin->(60)->GongHangQuKuanJi->(35)->BaiNianJiangTang
提示
很O疼的一道题。。。说出不少伤感事啊。两个最短路的算法都是可以用的,可以视情况选择你习惯的那个算法。
迪杰斯特算法。单源最短路。曾近想又用堆去做优先队列。。但是在鱼c教程看到一个循环就可以找到。
所以贪方便抄下来了。算法复杂度感觉还是 O(n^2)
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<assert.h>
#include<ctype.h>
#include<stdlib.h>
#define max 0xffffff
using namespace std;
char ads[32][100];
int vis[32];
int G[32][32];
int D[32];///用来存放起点到每个节点的长度
int pre[32];///每个节点的前驱
int p;
void init( )
{
for(int i = 0; i < p; i++)
for(int j=0; j < p; j++)
G[i][j] = max;
}
void print(int e)//输出。
{
if(e==pre[e]){printf("%s",ads[e]);return ;}
else print(pre[e]);
printf("->(%d)->%s",G[pre[e]][e],ads[e]);
}
void dijkstra(int start,int end)
{
for(int i = 0; i < p; ++i)
{
vis[i] = 0;
D[i] = G[start][i];
pre[i] = start;///前驱全部初始化为起点。这里刚刚写的时候没有 得不到正确答案。
// printf("%d %d\n",D[i],i);
}
//printf("\n__________________\n");
vis[start] = 1;
pre[start] = start;
D[start] = 0;
bool found = false;
int k;
for(int i = 0; i < p; i++)
{
int min = max;
int j;
for(j=0; j < p; j++) ///找到权最小的路径
{
if(!vis[j] && D[j]<min)
{ k = j;
min = D[j];
//printf("%d$$$\n",min);
}
}
vis[k] = 1;
for(j=0; j<p; j++) //修改曾有的路径
{
if(!vis[j]&&(min+G[k][j])<D[j])
{
D[j] = min + G[k][j];
pre[j] = k;
if(j == end)found = true;
}
}
for(j=0;j<p;j++)
/*printf("%4d",D[j]);
printf("\n");*/
if(found)break;
}
print(end);
}
int main()
{
// freopen("in.txt","r",stdin);
/// freopen("out.txt","w",stdout);
scanf("%d",&p);
int i,j;//计数器
for(i = 0; i < p; i++)
{
scanf("%s",ads[i]);
}
init();
int Q;
scanf("%d",&Q);
for(i=0; i<Q; i++)
{
int a1 = -1, b1= -1;
char a[100],b[100];
int W;
scanf("%s%s%d",a,b,&W);
for(j=0; j < p&&(a1==-1||b1==-1); j++)
{
if(!strcmp(a,ads[j]))a1 = j;
if(!strcmp(b,ads[j]))b1 = j;
}
G[a1][b1] = W;
G[b1][a1] = W;
//printf("%s_____%s\n\n%d........%d\n\nlen = %d}}}\\\n",a,b,a1,b1,G[a1][b1]);
}
// printf("()()()()(\n");
/*for(int i = 0; i < p; i++)
{
printf("ads%s=%d\n",ads[i],i);
}*/
int R;
scanf("%d",&R);
for(i=0; i<R; i++)
{
int a1 = -1, b1= -1;
char a[100],b[100];
int W;
scanf("%s%s",a,b);
for(j=0; j < p&&(a1==-1||b1==-1); j++)
{
if(!strcmp(a,ads[j]))a1 = j;
else if(!strcmp(b,ads[j]))b1 = j;
}
dijkstra(a1,b1);
printf("\n");
}
return 0;
}