您的位置:首页 > 其它

POJ 最短路径

2014-03-25 20:21 183 查看
这两天做了六道最短路径的问题,分别用了Dijkstra算法、SPFA算法和Floyd算法,甚至还有一道题用并查集做的也A了,感觉对短路径已经学得很不错了。

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();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: