HDU Today
来源:互联网 发布:学校结核病管理网络 编辑:程序博客网 时间:2024/06/05 03:47
经过锦囊相助,海东集团终于度过了危机,从此,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 Sample Output
这样住了一段时间,徐总对当地的交通还是不太了解。有时很郁闷,想去一个地方又不知道应该乘什么公交车,在什么地方转车,在什么地方下车(其实徐总自己有车,却一定要与民同乐,这就是徐总的性格)。
徐总经常会问蹩脚的英文问路:“Can you help me?”。看着他那迷茫而又无助的眼神,热心的你能帮帮他吗?
请帮助他用最短的时间到达目的地(假设每一路公交车都只在起点站和终点站停,而且随时都会开)。
第二行有徐总的所在地start,他的目的地end;
接着有n行,每行有站名s,站名e,以及从s到e的时间整数t(0<t<100)(每个地名是一个长度不超过30的字符串)。
note:一组数据中地名数不会超过150个。
如果N==-1,表示输入结束。
6xiasha westlakexiasha station 60xiasha ShoppingCenterofHangZhou 30station westlake 20ShoppingCenterofHangZhou supermarket 10xiasha supermarket 50supermarket westlake 10-1
50Hint:The best route is:xiasha->ShoppingCenterofHangZhou->supermarket->westlake虽然偶尔会迷路,但是因为有了你的帮助**和**从此还是过上了幸福的生活――全剧终――
邻接矩阵的dijkstra
#include<stdio.h>#include<iostream>#include<cstring>#include<map>using namespace std;/*这种方式还是比较可以接受的,就是占用的空间比较大,是直接进行矩形的距离赋值,如果比较大就不太好了但是操作比较简单,但是有冗余的操作,就是那个查找,浪费了很多时间而我们用队列来优化的话,我们就不会再去找这些vis[]的了,但是用优先队列,很麻烦,需要写的东西实在太多,不太好*/const int maxn=20010;//因为是双向边,所以我们需要是T*2const int INF=0x3f3f3f3f;int dis[160];int vis[160];int len[200][200];int n;map<string,int> station;//将车站编号string st,ed;int dijkstra(int st_,int end_){ memset(vis,0,sizeof(vis)); for(int i=1;i<=end_;i++) dis[i]=INF; dis[st_]=0;//自己到自己的距离就是0 for(int i=st_;i<=end_;i++) { int j,m; int temp=INF; for( j=st_;j<=end_;j++) { if(!vis[j]&&dis[j]<temp)//还没有在合并的里面 都是找最近的那个点来松弛 { temp=dis[j]; m=j; } } vis[m]=1;//标记这个最小值点 if(temp==INF)//找不到能松弛的了,那我们就可以提前退出 break; for(int k=st_;k<=end_;k++)//对所有的点进行松弛操作 { if(dis[k]>temp+len[m][k]) dis[k]=temp+len[m][k]; } } return dis[station[ed]];}int main(){ while(~scanf("%d",&n)) { int it=1; if(n==-1) break; station.clear();//清空映射 memset(len,INF,sizeof(len)); cin>>st>>ed; if(!station[st]) station[st]=it++; if(!station[ed]) station[ed]=it++; for(int i=1;i<=n;i++) { string u,v;int w; cin>>u>>v>>w; if(!station[u])//之后没有出现的这样写就好了,感觉还是很好的,就是一个对地名的编号 station[u]=it++; if(!station[v]) station[v]=it++; int x=station[u],y=station[v]; len[x][y]=len[y][x]=w;//直接赋值权重 } if(station[st]==station[ed]) { printf("0\n"); continue; } int ans=dijkstra(1,it-1); if(ans==INF) printf("-1\n"); else printf("%d\n",ans); } return 0;}
前向星的dijkstra
#include<bits\stdc++.h>using namespace std;const int maxn=20010;//因为是双向边,所以我们需要是T*2const int INF=0x3f3f3f3f;int dis[maxn];int vis[maxn];int head[maxn];map<string,int> station;//将车站编号int n;int cnt;string st,ed;struct edge{ int v,w; int next;}Edge[maxn];void add_edge(int u,int v,int w){ Edge[cnt].v=v; Edge[cnt].w=w; Edge[cnt].next=head[u]; head[u]=cnt++;}typedef struct node{ int point,distance; node(){} node(int _point,int _distance){point=_point,distance=_distance;} bool operator < (const node& other)const { return distance >other.distance; }}Node;int dijkstra(int s){ for(int i=1;i<=n;i++) dis[i]=INF; memset(vis,0,sizeof(vis)); Node now,next; dis[s]=0; priority_queue<Node> pq; pq.push(node(s,dis[0])); while(pq.size()) { now=pq.top(); pq.pop(); // if(vis[now.point])//怎么会在最短之后又进入呢,事实证明这里没有必要再去写这个vis[],我们都是从小到大去松弛,所以不会出现后面更小的情况 // continue; // vis[now.point]=1; for(int i=head[now.point];i!=-1;i=Edge[i].next) { int to=Edge[i].v;//从当前点出发的点 if(dis[to]>dis[now.point]+Edge[i].w) { dis[to]=dis[now.point]+Edge[i].w; // if(to==station[ed]) // return dis[station[ed]]; pq.push(node(to,dis[to])); } } } return dis[station[ed]];}int main(){ while(~scanf("%d",&n)) { cnt=0;int it=1; memset(head,-1,sizeof(head)); memset(Edge,0,sizeof(Edge)); if(n==-1) break; station.clear();//清空映射 cin>>st>>ed; if(!station[st]) station[st]=it++; if(!station[ed]) station[ed]=it++; for(int i=1;i<=n;i++) { string u,v;int w; cin>>u>>v>>w; if(!station[u])//之后没有出现的这样写就好了,感觉还是很好的,就是一个对地名的编号 station[u]=it++; if(!station[v]) station[v]=it++; add_edge(station[u],station[v],w);//对边进行记录 add_edge(station[v],station[u],w);// } if(station[st]==station[ed])//因为他要是同一个点的话,我们是不能重复访问一个点的,所以得把这种情况排除 { printf("0\n"); continue; } int ans=dijkstra(1);//传入起点,距离就是指的距离1的距离了 if(ans==INF) printf("-1\n"); else printf("%d\n",ans); } return 0;}
前向星的spfa
#include<bits\stdc++.h>using namespace std;/*发现还是spfa这种算法好用,一个是代码量比较少,再就是还能判断有没有负环功能比较强大,主要是那个digkstra算法,用优先队列来实现实在是太复杂了,还得造一个节点结构体,还得写比较函数实在是麻烦*/const int maxn=20010;//因为是双向边,所以我们需要是T*2const int INF=0x3f3f3f3f;int dis[maxn];int vis[maxn];int head[maxn];map<string,int> station;//将车站编号int n;int cnt;string st,ed;struct edge{ int v,w; int next;}Edge[maxn];void add_edge(int u,int v,int w){ Edge[cnt].v=v; Edge[cnt].w=w; Edge[cnt].next=head[u]; head[u]=cnt++;}int spfa(int s){ int time[maxn]; memset(time,0,sizeof(time));//检测访问的次数 memset(vis,0,sizeof(vis));//是否访问过 for(int i=1;i<=n;i++) dis[i]=INF; dis[s]=0;vis[s]=1;time[s]++; queue<int> q; q.push(s); while(q.size()) { int now=q.front(); q.pop(); vis[now]=0;//之后我们还能放回来,记住 for(int i=head[now];i!=-1;i=Edge[i].next) { int to=Edge[i].v; if(Edge[i].w+dis[now]<dis[to]) { dis[to]=Edge[i].w+dis[now]; if(!vis[to])//只有松弛成功并且现在没有在队列里面的才可以进入队列 { vis[to]=1; time[to]++; q.push(to); if(time[to] >= n)//存在负环,没有最小的路径 return -1; } } } } return dis[station[ed]];}int main(){ while(~scanf("%d",&n)) { cnt=0;int it=1; memset(head,-1,sizeof(head)); memset(Edge,0,sizeof(Edge)); if(n==-1) break; station.clear();//清空映射 cin>>st>>ed; if(!station[st]) station[st]=it++; if(!station[ed]) station[ed]=it++; for(int i=1;i<=n;i++) { string u,v;int w; cin>>u>>v>>w; if(!station[u])//之后没有出现的这样写就好了,感觉还是很好的,就是一个对地名的编号 station[u]=it++; if(!station[v]) station[v]=it++; add_edge(station[u],station[v],w);//对边进行记录 add_edge(station[v],station[u],w);// } if(station[st]==station[ed])//因为他要是同一个点的话,我们是不能重复访问一个点的,所以得把这种情况排除 { printf("0\n"); continue; } int ans=spfa(1);//传入起点,距离就是指的距离1的距离了 if(ans==INF) printf("-1\n"); else printf("%d\n",ans); } return 0;}
阅读全文
0 0
- HDU Today
- HDU Today
- HDU Today
- HDU Today
- HDU Today
- HDU Today
- hdu today
- HDU Today
- HDU Today
- HDU Today
- HDU 2112 HDU Today
- hdu 2112 HDU Today
- Hdu-2112 HDU Today
- hdu 2112 HDU Today
- HDU 2112 HDU Today
- hdu 2112 HDU Today
- HDU 2112 HDU Today
- hdu 2112 HDU Today
- CISCO VPN Client Reason 442 WIN8/10错误解决方案
- 牛客网刷题笔记--树
- oracle基本操作
- C语言基础(七)字符串 类型重定义 结构体
- abap 向上取整CEIL和向下取整FLOOR
- HDU Today
- PrepareStatement与Statement的区别
- ASP服务器小程序 免配置很方便
- [总结]C语言真是博大精深(一)
- HDU 6063 RXD and math+(快速幂)+多校联赛第三场
- Python3学习(3)--基础篇
- [一天一项目]120+项目构思
- 卡在Authenticating with iTunes Store(This action could not be completed. Try Again -22421)的解决方法
- 设计公司要包装自己