HDU Today
Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 23075 Accepted Submission(s): 5522
Problem Description
经过锦囊相助,海东集团终于度过了危机,从此,HDU的发展就一直顺风顺水,到了2050年,集团已经相当规模了,据说进入了钱江肉丝经济开发区500强。这时候,XHD夫妇也退居了二线,并在风景秀美的诸暨市浬浦镇陶姚村买了个房子,开始安度晚年了。
这样住了一段时间,徐总对当地的交通还是不太了解。有时很郁闷,想去一个地方又不知道应该乘什么公交车,在什么地方转车,在什么地方下车(其实徐总自己有车,却一定要与民同乐,这就是徐总的性格)。
徐总经常会问蹩脚的英文问路:“Can you help me?”。看着他那迷茫而又无助的眼神,热心的你能帮帮他吗?
请帮助他用最短的时间到达目的地(假设每一路公交车都只在起点站和终点站停,而且随时都会开)。
Input
输入数据有多组,每组的第一行是公交车的总数N(0<=N<=10000);
第二行有徐总的所在地start,他的目的地end;
接着有n行,每行有站名s,站名e,以及从s到e的时间整数t(0<t<100)(每个地名是一个长度不超过30的字符串)。
note:一组数据中地名数不会超过150个。
如果N==-1,表示输入结束。
Output
如果徐总能到达目的地,输出最短的时间;否则,输出“-1”。
Sample Input
6
xiasha westlake
xiasha station 60
xiasha ShoppingCenterofHangZhou 30
station westlake 20
ShoppingCenterofHangZhou supermarket 10
xiasha supermarket 50
supermarket westlake 10
-1
Sample Output
50
Hint:
The best route is:
xiasha->ShoppingCenterofHangZhou->supermarket->westlake
虽然偶尔会迷路,但是因为有了你的帮助
**和**从此还是过上了幸福的生活。
――全剧终――
Total Submission(s): 23075 Accepted Submission(s): 5522
Problem Description
经过锦囊相助,海东集团终于度过了危机,从此,HDU的发展就一直顺风顺水,到了2050年,集团已经相当规模了,据说进入了钱江肉丝经济开发区500强。这时候,XHD夫妇也退居了二线,并在风景秀美的诸暨市浬浦镇陶姚村买了个房子,开始安度晚年了。
这样住了一段时间,徐总对当地的交通还是不太了解。有时很郁闷,想去一个地方又不知道应该乘什么公交车,在什么地方转车,在什么地方下车(其实徐总自己有车,却一定要与民同乐,这就是徐总的性格)。
徐总经常会问蹩脚的英文问路:“Can you help me?”。看着他那迷茫而又无助的眼神,热心的你能帮帮他吗?
请帮助他用最短的时间到达目的地(假设每一路公交车都只在起点站和终点站停,而且随时都会开)。
Input
输入数据有多组,每组的第一行是公交车的总数N(0<=N<=10000);
第二行有徐总的所在地start,他的目的地end;
接着有n行,每行有站名s,站名e,以及从s到e的时间整数t(0<t<100)(每个地名是一个长度不超过30的字符串)。
note:一组数据中地名数不会超过150个。
如果N==-1,表示输入结束。
Output
如果徐总能到达目的地,输出最短的时间;否则,输出“-1”。
Sample Input
6
xiasha westlake
xiasha station 60
xiasha ShoppingCenterofHangZhou 30
station westlake 20
ShoppingCenterofHangZhou supermarket 10
xiasha supermarket 50
supermarket westlake 10
-1
Sample Output
50
Hint:
The best route is:
xiasha->ShoppingCenterofHangZhou->supermarket->westlake
虽然偶尔会迷路,但是因为有了你的帮助
**和**从此还是过上了幸福的生活。
――全剧终――
题解:这道题主要是这些地点的存放问题,将地点转化为普通的数字即可。下面采用的是用map来存放的。ma[a]=1; ma[b]=2; int t=3; for(int i=0; i<n; i++) { int x; scanf("%s%s%d",c,d,&x); if(!ma[c]) ///如果与起点和终点不同的话换成新的数字 ma[c]=t++; if(!ma[d]) ma[d]=t++; m[ma[c]][ma[d]]=m[ma[d]][ma[c]]=x;///双向的 }
利用map的存放转化为了数字型然后按照Dijstar算法
代码如下:
#include <iostream> #include <algorithm> #include <cstring> #include <string> #include <cstdio> #include <map> #define N(n,m) memset(n,m,sizeof(n)); using namespace std; const int maxx=230; const int INF = 0x3f3f3f3f; int dis[maxx];///不超过150 个地名(暂时存放距离,最终存放的是最小的距离) int book[maxx];///记录点是否被访问过(与点相连的边都被访问过) int m[maxx][maxx];///存放各点间的距离 int n; ///对book和m的初始化 void init() { N(book,0); N(m,INF); } ///dijstra算法 void Dijstra(int start,int end) { int i,k; for(i=start; i<=end; i++) dis[i]=m[start][i];///存放start到其他地点的距离 dis[start]=0; ///到本身的距离为0 book[start]=1;///start被访问(找到与start相连的最小的距离) int u; for(k=start; k<=end; k++) { int minn=INF; for(int i=start; i<=end; i++) { if(book[i]==0&&dis[i]<minn)///找到start到某个点的最小的那个距离 { minn=dis[i]; u=i; } } book[u]=1; ///标记 for(int v=start; v<=end; v++) { if(m[u][v]<INF&&book[v]==0) { if(dis[v]>dis[u]+m[u][v]) dis[v]=dis[u]+m[u][v];///改变距离 } } } } int main() { map<string ,int >ma; while(scanf("%d %d",&n)&&n!=-1) { int flag=0;///记录如果是原点 char a[maxx],b[maxx],c[maxx],d[maxx]; ma.clear();///map初始化 init(); ///初始化函数 scanf("%s%s",a,b); if(!strcmp(a,b)) { flag=1; ///判断是否在同一点 } ma[a]=1; ma[b]=2; int t=3; for(int i=0; i<n; i++) { int x; scanf("%s%s%d",c,d,&x); if(!ma[c]) ///如果与起点和终点不同的话换成新的数字 ma[c]=t++; if(!ma[d]) ma[d]=t++; m[ma[c]][ma[d]]=m[ma[d]][ma[c]]=x;///双向的 } if(flag) { printf("0\n");///原点输出0 continue; } Dijstra(1,t); ///Dijstra算法 if(dis[2]==INF) { printf("-1\n"); ///如果两者之间没有公交可以到达输出-1; } else printf("%d\n",dis[2]);///将state到end=2 的结果输出 } return 0; }