POJ 最短路径
2014-03-25 20:21
183 查看
这两天做了六道最短路径的问题,分别用了Dijkstra算法、SPFA算法和Floyd算法,甚至还有一道题用并查集做的也A了,感觉对短路径已经学得很不错了。
poj1860,poj3259,poj1062,poj2253,poj1125,poj2240
POj2253,Dijkstra和并查集都可以。
Dijkstra算法改变一下dis数组存的内容,计算方式也要相应的变一下。
Dijkstra算法AC代码:
并查集的话就是将n个点的所有边存到一个结构体中,按距离从小到大排序。对于每个边将边相连的两点用并查集连起来,并判断1点和2点是否已经相连,若没有则继续加边;若已经相连则最后连的边的距离就是最小的最长距离。
由于要对所有边进行排序,时间复杂度为O(n^2logn),相比Dijkstra的O(n^2)要大一些,但在POJ上时间都是16MS。
并查集AC代码如下:
poj1860,poj3259,poj1062,poj2253,poj1125,poj2240
POj2253,Dijkstra和并查集都可以。
Dijkstra算法改变一下dis数组存的内容,计算方式也要相应的变一下。
Dijkstra算法AC代码:
#include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <queue> #include <algorithm> #include <cmath> using namespace std; const double INF = 100000000; const int maxn = 210; double dis[maxn],g[maxn][maxn],N; bool v[maxn]; int m,n; vector<pair<int,int> > a; double dist(pair<int,int> a,pair<int,int> b) { return sqrt((double)(a.first-b.first)*(a.first-b.first) +(a.second-b.second)*(a.second-b.second)); } void dijkstra(){ for (int i = 1;i<=N ;i++ )dis[i] = INF; dis[1] = 0; memset(v,0,sizeof v); for (int i = 1;i<=N ;i++ ) { int mark = -1,mindis = INF; for(int j = 1;j<=N;j++) if(!v[j] && dis[j]<mindis){ mindis=dis[j]; mark = j; } if(mark == -1) return ; v[mark] = 1; for(int j=1;j<=N;j++) if(!v[j]) dis[j] = min(dis[j],max(dis[mark],g[mark][j])); } } void slove() { int x,y; a.clear(); for (int i = 1;i<=n ;i++ ) { scanf("%d%d",&x,&y); a.push_back(make_pair(x,y)); } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) g[i][j] = g[j][i] = dist(a[i-1],a[j-1]); N = n; dijkstra(); printf("%.3f\n\n",dis[2]); } int main() { #ifdef ARTHUR_YANG freopen("in.txt","r",stdin); #endif // ARTHUR_YANG int t=1; while(~scanf("%d",&n) && n) { printf("Scenario #%d\nFrog Distance = ",t++); slove(); } }
并查集的话就是将n个点的所有边存到一个结构体中,按距离从小到大排序。对于每个边将边相连的两点用并查集连起来,并判断1点和2点是否已经相连,若没有则继续加边;若已经相连则最后连的边的距离就是最小的最长距离。
由于要对所有边进行排序,时间复杂度为O(n^2logn),相比Dijkstra的O(n^2)要大一些,但在POJ上时间都是16MS。
并查集AC代码如下:
#include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <queue> #include <algorithm> #include <cmath> using namespace std; int n; struct k { int a,b; double dist; friend bool operator<(k a,k b) { return a.dist<b.dist; } }g[44444]; struct DisjointSet{ vector<int> father,rank; DisjointSet(int n) : father(n),rank(n){ for(int i =0;i<n;i++) father[i] = i; } int find(int v) { return father[v] = father[v]==v ? v: find(father[v]); } void merge(int x,int y) { int a = find(x),b = find(y); if(rank[a]<rank[b]) father[a] = b; else { father[b] = a; if(rank[b] == rank[a]) rank[a] ++; } } }; int num; vector<pair<int,int> > a; double dist(pair<int,int> a,pair<int,int> b) { return sqrt((double)(a.first-b.first)*(a.first-b.first) +(a.second-b.second)*(a.second-b.second)); } void slove() { int x,y; a.clear(); num = 0; for (int i = 1;i<=n ;i++ ) { scanf("%d%d",&x,&y); a.push_back(make_pair(x,y)); } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { if(i==j) continue; g[num].a = i; g[num].b = j; g[num++].dist = dist(a[i-1],a[j-1]); } sort(g,g+num); DisjointSet di(n+1); for (int i=0;i<num ;i++ ) { di.merge(g[i].a,g[i].b); if(di.find(1) == di.find(2)) { printf("%.3f\n\n",g[i].dist); return ; } } } int main() { #ifdef ARTHUR_YANG freopen("in.txt","r",stdin); #endif // ARTHUR_YANG int t=1; while(~scanf("%d",&n) && n) { printf("Scenario #%d\nFrog Distance = ",t++); slove(); } }
相关文章推荐
- poj 1797 dijkstra最短路径
- poj 1847 最短路径的dijkstra算法
- 最短路径?青蛙(Frogger), ZOJ1942, POJ2253
- 算法训练之BFS POJ 2251 Dungeon Master 三维最短路径
- POJ-2387 Til the Cows Come Home(Dijsktra算法求最短路径)
- POJ 3169 Layout ( 最短路径、差分约束)
- Poj 2387 Til the Cows Come Home(Dijkstra 最短路径)
- http://poj.org/problem?id=1125 最短路径
- POJ 3835 Columbus's bargain (最短路径 spfa 算法)
- POJ_1502_MPI Maelstrom_最短路径
- poj2449 第k短路 (单源最短路径+A*)
- POJ 2391 Ombrophobic Bovines (二分,最短路径,网络流sap,dinic,预留推进 )
- [POJ](2387)Til the Cows Come Home---单源最短路径(图)
- POJ 3249 Test for Job DAG图上的单源最短路径
- poj_1502_MPI Maelstrom(Dijkstra求单源最短路径)
- 次最短路径 POJ 3255 Roadblocks
- POJ 3249 Test for Job (DAG图上的单源最短路径) 最详细的图解
- poj 3311(状态压缩DP的最短路径)
- [最短路径] POJ 1062 - 昂贵的聘礼
- poj_1135_最短路径&枚举