链接:http://acm.hdu.edu.cn/showproblem.php?pid=1598
Problem Description
Input
输入包括多个测试实例,每个实例包括:第一行有2个正整数n (1<n<=200)和m (m<=1000),表示有N个城市和M条SARS。
接下来的行是三个正整数StartCity,EndCity,speed,表示从表面上看StartCity到EndCity,限速为speedSARS。speed<=1000000
然后是一个正整数Q(Q<11),表示寻路的个数。
接下来Q行每行有2个正整数Start,End, 表示寻路的起终点。
Output
每个寻路要求打印一行,仅输出一个非负整数表示最佳路线的舒适度最高速与最低速的差。如果起点和终点不能到达,那么输出-1。
Sample Input
1 2 2
2 3 4
1 4 1
3 4 2
2
1 3
1 2
Sample Output
10
Author
ailyanlu
Source
HDU 2007-Spring Programming Contest - Warm Up (1)
Recommend
8600
大意——给你n个城市和n个城市之间的m条道路以及每条道路上的固定速度,然后对你提出Q个问题,问题形式为从某个城市到达某个城市。问:找到某条路径,使得这条路径上的最大固定速度与最小固定速度之差最小,并且输出最小差,如果不能到达,则输出-1。
思路——因为要求最大固定速度与最小固定速度之差,所以我们可以将各路径按照固定速度从小到大进行排序,然后再逐个枚举各个固定速度,从各个固定速度往后面找,利用并查集的性质,直到起点和终点属于同一个集合为止,接着用最大固定速度减去最小固定速度,将其值与minc(结果,一开始置为无穷大)比较,小的话将其值给minc。如果minc最后还为无穷大,则说明其到达不了终点,输出-1。
复杂度分析——时间复杂度:O(Q*m*(n+m)),空间复杂度:O(n+m)
附上AC代码:
#include <iostream>
#include <cstdio>
#include <string>
#include <cmath>
#include <iomanip>
#include <ctime>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <set>
#include <map>
using namespace std;
typedef unsigned int UI;
typedef long long LL;
typedef unsigned long long ULL;
typedef long double LD;
const double pi = acos(-1.0);
const double e = exp(1.0);
const double eps = 1e-8;
const int inf = 0x3f3f3f3f;
const int maxn = 205;
const int maxm = 1005;
struct edge
{
int a, b;
int w;
bool operator < (const edge & p) const{
return w < p.w;
}
} edg[maxm];
int father[maxn];
int n, m;
int find(int x);
void init();
int main()
{
ios::sync_with_stdio(false);
while (scanf("%d%d", &n, &m) != EOF)
{
for (int i=0; i<m; i++)
scanf("%d%d%d", &edg[i].a, &edg[i].b, &edg[i].w);
sort(edg, edg+m);
int query, minc;
int start, end;
int a, b, j;
scanf("%d", &query);
while (query--)
{
scanf("%d%d", &start, &end);
minc = inf;
for (int i=0; i<m; i++)
{
init();
for (j=i; j<m; j++)
{
a = find(edg[j].a);
b = find(edg[j].b);
if (a != b)
father[a] = b;
if (find(start) == find(end))
{
if (minc > edg[j].w-edg[i].w)
minc = edg[j].w-edg[i].w;
break;
}
}
if (j == m)
break;
}
if (minc == inf)
printf("-1\n");
else
printf("%d\n", minc);
}
}
return 0;
}
int find(int x)
{
while (x != father[x])
x = father[x];
return x;
}
void init(void)
{
for (int i=1; i<=n; i++)
father[i] = i;
}