题意:坐标轴上给出了n个点的坐标,求顶点1 2之间的最短路。这里最短路的定义为:1到2的所有路径中,各路径最长边中的最小值。 (2<=n<=200)
思路:传统意义上最短路是顶点路径的边权之和,这里改成边的最大值即可。
用Floyd和dijkstra都可以做。
思路见代码。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<stdlib.h>
#include<string.h>
#include<string>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<math.h>
#include<set>
using namespace std;
const int maxn = 2e2+7;
const int INF = 0x3f3f3f;
#define ll long long
//坐标轴上给定一些点
int coor[maxn][2];
double g[maxn][maxn];
int n;
int cnt=1;
struct node
{
double d;//1到v某条路径上的最长边
int v;
friend bool operator < (const node &a,const node &b)
{
return a.d>b.d;//队首是1到v所有路径最长边中的最小值
//由此保证每次取出的是最短路点
}
}h;
double dis(int x1,int y1,int x2,int y2)
{
return sqrt((x1-x2)*1.0*(x1-x2)+(y1-y2)*1.0*(y1-y2));
}
void floyd()
{
//状态转移过程中,用来松弛的东西从边权和变成了边权最大值
for(int i=1;i<=n;i++)//注意枚举的中间点要放在第一层,具体可以看看算法导论相关部分
{
for(int j=1;j<=n;j++)
{
for(int k=1;k<=n;k++)
{
g[j][k]=min(g[j][k],max(g[j][i],g[i][k]));
}
}
}
}
void dijkstra()
{
priority_queue<node>q;
node t;
double dist[maxn];//1到i的所有路径中最长边中的最短情况
fill(dist,dist+maxn,INF);
bool vis[maxn]={0};
dist[1]=0;
t.d=0.0,t.v=1;
q.push(t);
while(q.size())
{
h=q.top(),q.pop();
if(vis[h.v]) continue;
vis[h.v]=1;
for(int i=2;i<=n;i++)
{
if(dist[i] > max(dist[h.v],g[h.v][i]))//最短路根据边权最大值判定,dist[h.v]是1到h.v路径边最大值中的最小值,需要和h.v到i的边 取max
{
dist[i] = max(dist[h.v],g[h.v][i]);
t.d=dist[i],t.v=i;
q.push(t);
}
}
}
g[1][2]=dist[2];//保存答案
}
int main()
{
while(1)
{
scanf("%d",&n);
if(!n) break;
for(int i=1;i<=n;i++)
{
scanf("%d %d",coor[i],coor[i]+1);
}
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
g[i][j]=g[j][i]=dis(coor[i][0],coor[i][1],coor[j][0],coor[j][1]);
}
}
// floyd();
dijkstra();
printf("Scenario #%d\nFrog Distance = %.3f\n\n",cnt++,g[1][2]);
}
return 0;
}
Heavy Transportation POJ - 1797
这题和上面那题目标刚好相反,
上一题的最短路定义为:所有路径中最长边的最短情况 ,
这题的最短路定义为:所有路径中最短边的最长情况。
做法还是一样的。 只不过是要改成算最长路。
数据范围是1000,不能用floyd算法。
下面贴dijkstra做法:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<stdlib.h>
#include<string.h>
#include<string>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<math.h>
#include<set>
using namespace std;
const int maxn =1e3+7;
const int INF =1e6+7;
int n,m;
int dist[maxn];//1到n的路径中 最短边的最长情况
struct node
{
int d,v;//d是 到v的某条路径上的最短边
friend bool operator < (const node &b,const node &a)
{
return b.d < a.d;//保证每次从堆取出的是1到v所有路径上最短边的最长情况
//也就是每次取出的点都是最短路点
}
}h,t;
priority_queue<node> q;
bool vis[maxn];
void Init()
{
memset(dist,0,sizeof(dist));
memset(vis,0,sizeof(vis));
while(q.size()) q.pop();
}
int g[maxn][maxn];
void dijkstra()
{
Init();
dist[1]=INF;
t.v=1,t.d=INF;
q.push(t);
while(q.size())
{
h=q.top();q.pop();
if(vis[h.v]) continue;
vis[h.v]=1;
for(int i=2;i<=n;i++)
{
if(g[h.v][i]!=INF && !vis[i] && dist[i]<min(dist[h.v],g[h.v][i]))
{
dist[i]=min(dist[h.v],g[h.v][i]);
t.d=dist[i],t.v=i;
q.push(t);
}
}
}
printf("%d\n\n",dist[n]);
}
int main()
{
int t,cnt=1;
scanf("%d",&t);
while(t--)
{
fill(g[0],g[0]+maxn*maxn,INF);
scanf("%d %d",&n,&m);
for(int i=1;i<=m;i++)
{
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
g[a][b]=g[b][a]=min(c,g[a][b]);
}
printf("Scenario #%d:\n",cnt++);
dijkstra();
}
return 0;
}