您的位置:首页 > 其它

HDU-4511 小明系列故事——女友的考验 floyd变种-标号递增最短路

2013-10-04 16:02 357 查看
题意:给定N个点,现在要求出从1号点到N号点的最短路。题目给的限制条件就是对于某条路径是不能够走的,但是可以选择某段路径走,另外就是所走的路径的标号必须是递增的。

分析:由于给定的是一些列的坐标点,这也就说原图其实是一个完全图。对于限制路径,其实只要限制的路径上点数超过2,那么明显可以选择从起点直接走到终点这条最短路来代替限制路径,因此该限制不起作用,而对于限制路径上点数为2的路径则需要标记一下不能够取。对于最终路径要求点坐标路径递增这一条件则直接在floyd处理的时候限制好i,j,k三者的关系即可。

#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define sqr(x) ((x)*(x))
using namespace std;

const int N = 55;
const double eps = 1e-8;
int n, m;
int seq
;
double mp

;

int sign(const double &x) {
return x < -eps ? -1 : x > eps ? 1 : 0;
}

struct Point {
double x, y;
bool operator == (const Point &t) const {
return !sign(x-t.x) && !sign(y-t.y);
}
}p
;

double dist(int a, int b) {
return sqrt(sqr(p[a].x-p[b].x) + sqr(p[a].y-p[b].y));
}

void floyd() {
for (int k = 0; k < n; ++k) {
for (int i = 0; i < k; ++i) {
if (!sign(mp[i][k]+1)) continue;
for (int j = k+1; j < n; ++j) {
if (!sign(mp[k][j]+1)) continue;
if (!sign(mp[i][j]+1) || sign(mp[i][j]-(mp[i][k]+mp[k][j])) > 0) {
mp[i][j] = mp[i][k] + mp[k][j];
}
}
}
}
}

int main() {
while (scanf("%d %d", &n, &m), n|m) {
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) mp[i][j] = 0;
scanf("%lf %lf", &p[i].x, &p[i].y);
}
int t;
for (int i = 0; i < m; ++i) {
scanf("%d", &t);
for (int j = 0; j < t; ++j) {
scanf("%d", &seq[j]);
}
if (t == 2 && !(p[seq[0]-1] == p[seq[1]-1])) {
mp[seq[0]-1][seq[1]-1] = mp[seq[1]-1][seq[0]-1]= -1;
}
}
for (int i = 0; i < n; ++i) {
for (int j = i+1; j < n; ++j) {
if (sign(mp[i][j]+1)) mp[i][j] = mp[j][i] = dist(i, j);
}
}
floyd();
if (sign(mp[0][n-1]+1)) printf("%.2f\n", mp[0][n-1]);
else puts("Can not be reached!");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: