hdu2482 transit search
2015-09-12 20:58
288 查看
第一次做大牛们口中的“阅读题”,顿时感觉智商被碾压...
虽然读懂题意后就是很简单的最短路,但网上大牛们不带注释的题解对于博主这种弱渣简直同天书一般orz
于是AC后将此(水)题整理一下,加些注释,以方便查阅,大牛们飘过就好orz
题目大意:给出起点、终点、车站的位置和一些公交线路,分三种情况输出:(1)起点离终点够近,走过去;(2)起点离终点太远,但起点和终点附近都有车站,求最小乘车数(一站到底就是1,每换乘1趟+1);(3)起点离终点太远,且附近无车站,或者不可达,就打出租车;
将乘车数看做距离就是最短路问题了,大概有三种建图方法:http://blog.csdn.net/qq564690377/article/details/8053877,这里博主采用的是最后一种
拿第二组输入为例,建好图后大概像这样:
![](http://img.blog.csdn.net/20150912211934054?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
很容易就看出从起点到终点要上下车共4次,也就是搭两趟车
这方法挺神奇的...不用考虑重复建点(两线路都过b点的话建两个点)
这题貌似有个神奇的结论:从起点走到车站,不搭公车,直接走到终点,应该会输出一个0(博主没试过)。当然就结果而言这是对的,不过有些微妙。
虽然读懂题意后就是很简单的最短路,但网上大牛们不带注释的题解对于博主这种弱渣简直同天书一般orz
于是AC后将此(水)题整理一下,加些注释,以方便查阅,大牛们飘过就好orz
题目大意:给出起点、终点、车站的位置和一些公交线路,分三种情况输出:(1)起点离终点够近,走过去;(2)起点离终点太远,但起点和终点附近都有车站,求最小乘车数(一站到底就是1,每换乘1趟+1);(3)起点离终点太远,且附近无车站,或者不可达,就打出租车;
将乘车数看做距离就是最短路问题了,大概有三种建图方法:http://blog.csdn.net/qq564690377/article/details/8053877,这里博主采用的是最后一种
拿第二组输入为例,建好图后大概像这样:
很容易就看出从起点到终点要上下车共4次,也就是搭两趟车
这方法挺神奇的...不用考虑重复建点(两线路都过b点的话建两个点)
这题貌似有个神奇的结论:从起点走到车站,不搭公车,直接走到终点,应该会输出一个0(博主没试过)。当然就结果而言这是对的,不过有些微妙。
#include<bits/stdc++.h> #define maxv 5010 using namespace std; const int len[8]={5120,2560,1280,640,320,160,80,40}; struct Point{ int x,y;//点的位置(x,y) inline void read(){cin>>x>>y;}//读入点的位置 inline void readFromS(){//单独处理start和end string s; int rx,ry; cin>>s>>rx>>ry; int dx=0,dy=0; for(int i=0;i<8;i++){ if(s[i]=='1'||s[i]=='3') dy+=len[i]; if(s[i]=='2'||s[i]=='3') dx+=len[i]; } x=dx+(rx<<2);y=dy+(ry<<2); } double Length(Point b){return sqrt((double)(x-b.x)*(x-b.x)+(double)(y-b.y)*(y-b.y));}//求距离 }ps[maxv],&star=ps[0],&fin=ps[1];//实点集,0为start,1为end struct Edge{ int to,cost; Edge(int to,int cost):to(to),cost(cost){} }; vector<Edge> G[maxv+200];//邻接表 int inf,d[maxv];//d[]记录上下车次数(距离) typedef pair<int,int> P;<dist,node> void Dijkstra(){//最短路,没什么要讲的吧? priority_queue<P,vector<P>,greater<P> > p; memset(d,0x0f,sizeof d); inf=d[1],d[0]=0; p.push(P(0,0)); while(!p.empty()&&d[1]==inf){ int v=p.top().second,cost=p.top().first;p.pop(); if(d[v]<cost) continue; int size=G[v].size(); for(int i=0;i<size;i++){ Edge e=G[v][i]; if(d[e.to]>d[v]+e.cost){ d[e.to]=d[v]+e.cost; p.push(P(d[e.to],e.to)); } } } } bool hasline,tooshort; const string walk("walk there"),taxi("take a taxi"); void SOLVE() { if(tooshort) {cout<<walk<<endl;return;}//太短 else if(!hasline) {cout<<taxi<<endl;return;}//start或end的其中之一离车站过远 Dijkstra(); if(d[1]==inf) cout<<taxi<<endl; else cout<<(d[1]>>1)<<endl;//乘车次数=上下车次数和/2 } void INPUT() { int N,M; //start和end建点 star.readFromS();fin.readFromS(); tooshort=star.Length(fin)<=2000.0;//太短 G[0].clear(),G[1].clear(); //对每个车站分别建点 map<string,int> m;//将车站名转为数字 cin>>N; string s; int tot=2; while(N--){ cin>>s; m[s]=tot; ps[tot++].read(); } //给距离start或end一千米以内的车站连单向边(start->车站 或 车站->end) bool sto=false,tof=false; for(int i=2;i<tot;i++){ G[i].clear(); if(star.Length(ps[i])<=1000.0) G[0].push_back(Edge(i,0)),sto=true;//从start走到车站过程中不用上下车 if(fin.Length(ps[i])<=1000.0) G[i].push_back(Edge(1,0)),tof=true; } hasline=sto&&tof;//start和end是否都能到达车站 //给公交线路建点并将其连与对应车站连双向边(车站<->线路) cin>>M; int k; while(M--){ cin>>k; G[tot].clear(); while(k--){ cin>>s; int no=m[s]; G[tot].push_back(Edge(no,1));//下车 G[no].push_back(Edge(tot,1));//上车 } tot++; } } void MAIN() { int T; cin>>T; while(T--) INPUT(),SOLVE(); } int main() { ios::sync_with_stdio(false); //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); MAIN(); return 0; }
相关文章推荐
- leetcode笔记:Gas Station
- _25407739的博客 个人主页|我的博客
- 随手写了一个鸡肋的二叉树
- 神器
- systemd详解
- git push免密码
- 建造者模式(三):关于Director的进一步讨论,建造者模式总结
- SOCKET网络通信
- 第一次拿shell
- Mat中的depth、dims、channels、step、data、elemSize
- 自学QT之进度条
- 22_01_httpd虚拟主机
- C _数据结构 _线性表的顺序存储
- 学习日志---基本排序算法
- Android 使用ShardSDK实现社会化分享
- CentOS 7 之systemd管理
- Hadoop笔记十二之 java.io.IOException: expected org.apache.hadoop.io.LongWr
- 1102. Invert a Binary Tree (25)
- 街道最短路径问题
- 逆序数 HDOJ 4911 Inversion