[vijos1013] 强墙 /[uva393] 房间最短路问题
来源:互联网 发布:淘宝网买盗版课程 编辑:程序博客网 时间:2024/04/28 23:13
题目描述
在一个长宽均为10,入口出口分别为(0,5)、(10,5)的房间里,有几堵墙,每堵墙上有两个缺口,求入口到出口的最短路经。
输入格式
第一排为n(n<=20),墙的数目。
接下来n排,每排5个实数x,a1,b1,a2,b2。
x表示墙的横坐标(所有墙都是竖直的),a1-b1和a2-b2之间为空缺。
a1、b1、a2、b2保持递增,x1-xn也是递增的。
输出格式
输出最短距离,保留2位小数。
样例数据
样例输入
2
4 2 7 8 9
7 3 4.5 6 7
样例输出
10.06
题目分析
比较难建图的一道题
先把所有墙建成线段,将墙的两端作为结点建图,在图中所有结点间建边(但是边不能与墙相交),边权为欧几里德距离
然后跑一次dijkstra就可以了
代码写的有点智障
源代码
#include<algorithm>#include<iostream>#include<iomanip>#include<cstring>#include<cstdlib>#include<vector>#include<cstdio>#include<cmath>#include<queue>using namespace std;inline const int Get_Int() { int num=0,bj=1; char x=getchar(); while(x<'0'||x>'9') { if(x=='-')bj=-1; x=getchar(); } while(x>='0'&&x<='9') { num=num*10+x-'0'; x=getchar(); } return num*bj;}struct Point { double x,y;};double Dist(Point a,Point b) { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}struct Vector { double x,y;};Vector operator - (Point a,Point b) { Vector c; c.x=b.x-a.x; c.y=b.y-a.y; return c;}double Cross(Vector a,Vector b) { //叉积 return a.x*b.y-b.x*a.y;}bool Segment_Intersect(Point A,Point B,Point C,Point D) { //判断两线段是否相交 return (Cross((C-A),(D-A))*Cross((C-B),(D-B))<0)&&(Cross((A-C),(B-C))*Cross((A-D),(B-D))<0);}///////////////const int maxn=20005; //数组范围struct Edge { //前向星 int from,to; double dist;};struct HeapNode { double d; int u; //u为当前结点 bool operator < (HeapNode a) const { return d>a.d; }};struct Dijkstra { int n,m; vector<Edge> edges; //邻接表 vector<int> G[maxn]; //记录每个结点可以到达的结点 bool vst[maxn]; double dist[maxn]; int path[maxn]; //使用path记录最短路 void init(int n) { this->n=n; for(int i=1; i<=n; i++)G[i].clear(); edges.clear(); } void AddEdge(int from,int to,double dist) { edges.push_back((Edge) { from,to,dist }); m=edges.size(); G[from].push_back(m-1); } void main(int s) { //核心算法 priority_queue<HeapNode> Q; for(int i=1; i<=n; i++)dist[i]=1e10; dist[s]=0; path[s]=s; memset(vst,0,sizeof(vst)); Q.push((HeapNode) { 0,s }); while(!Q.empty()) { HeapNode Now=Q.top(); Q.pop(); if(vst[Now.u])continue; vst[Now.u]=1; for(int i=0; i<G[Now.u].size(); i++) { Edge& e=edges[G[Now.u][i]]; //边的信息 int Next=e.to; if(dist[Next]>dist[Now.u]+e.dist) { dist[Next]=dist[Now.u]+e.dist; path[Next]=Now.u; Q.push((HeapNode) { dist[Next],Next }); } } } }} ;/////////////// Point Start[105],End[105],P[105]; //障碍Dijkstra dij;int n,cnt=0,cnt1=0;int main() { scanf("%d",&n); P[++cnt1]=(Point) { 0,5 }; P[++cnt1]=(Point) { 10,5 }; for(int i=1; i<=n; i++) { double x,a1,b1,a2,b2; scanf("%lf%lf%lf%lf%lf",&x,&a1,&b1,&a2,&b2); Start[++cnt].x=x; Start[cnt].y=0; End[cnt].x=x; End[cnt].y=a1; Start[++cnt].x=x; Start[cnt].y=b1; End[cnt].x=x; End[cnt].y=a2; Start[++cnt].x=x; Start[cnt].y=b2; End[cnt].x=x; End[cnt].y=10; P[++cnt1]= (Point) { x,a1 }; P[++cnt1]= (Point) { x,b1 }; P[++cnt1]= (Point) { x,a2 }; P[++cnt1]= (Point) { x,b2 }; } dij.init(cnt1); for(int i=1; i<=cnt1; i++) for(int j=i+1; j<=cnt1; j++) { int bj=1; for(int k=1; k<=cnt; k++) if(Segment_Intersect(P[i],P[j],Start[k],End[k])) { bj=0; break; } if(bj==0)continue; dij.AddEdge(i,j,Dist(P[i],P[j])); dij.AddEdge(j,i,Dist(P[i],P[j])); } dij.main(1); printf("%0.2lf\n",dij.dist[2]); return 0;}
0 0
- [vijos1013] 强墙 /[uva393] 房间最短路问题
- 【u026】房间最短路问题
- poj 3114 强连通分量 + 最短路
- Poj 3114 强联通+最短路
- POJ 3114 强联通分量+最短路
- js 最短路问题
- 最短路问题
- poj1062(最短路问题)
- 最短路问题
- Matlab--最短路问题
- 最短路问题总结
- 最短路问题
- 最短路问题 小结
- poj1062 最短路问题
- 最短路问题 小结
- 最短路问题
- 最短路问题
- Arbitrage(最短路问题)
- Bird私房菜学习笔记1 命令记录
- RPL(7):RFC6550翻译(7)---Upward Routes
- 思维导图中头脑风暴的功能怎么用
- 2017美国数学建模MCM B题(离散型)翻译 收费后合并 (Merge After Toll)
- LCA板子
- [vijos1013] 强墙 /[uva393] 房间最短路问题
- windows 编码转换问题
- JAVAEE分页功能实现ver1.0
- Visual Studio vs 不用每次打开都打开项目
- P1354 Hanoi双塔问题
- http://blog.csdn.net/lh1611/article/details/6602223
- JVM学习笔记1
- <a>标签的href和onclick属性
- Java编码问题汇总(字符串转换举例)