TRAVEL
题目大意
给定一个 个点和 条边的无向图,每条边都有一个 的限制,请计算出从 到 的限制范围是多少(即路径上 尽量小, 尽量大)。
的数据 。
解题思路
考试时排序写错,惨丢 和 。
排序,然后枚举 ,根据 建边,用并查集判断是否联通,最后更新答案。
AC CODE
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define _ 20005
int read()
{
int x = 0;
char c = getchar();
while(c < '0' || c > '9') c = getchar();
while(c >= '0' && c <= '9')
{
x = x * 10 + c - '0';
c = getchar();
}
return x;
}
int mmax;
int n, m;
int ansk, ansl, ansr;
int fa[_ << 1];
int find(int x)
{
return fa[x] == x ? x : fa[x] = find(fa[x]);
}
void init()
{
for(int i = 1; i <= mmax; ++i) fa[i] = i;
}
struct abc
{
int u, v, l, r;
} k[_ << 1];
bool cmp(abc a, abc b)
{
if(a.r != b.r)
return a.r > b.r;
return a.l < b.l;
}
signed main()
{
n = read(), m = read();
for(int i = 1; i <= m; ++i)
{
k[i].u = read(), k[i].v = read(), k[i].l = read(), k[i].r = read();
mmax = max(mmax, max(k[i].u, k[i].v));
}
sort(k + 1, k + m + 1, cmp);
for(int i = 1; i <= m; ++i)
{
init();
int r = INT_MAX;
for(int j = 1; j <= m; ++j)
{
if(k[j].l <= k[i].l)
{
int uu = find(k[j].u), vv = find(k[j].v);
if(uu != vv)
{
fa[vv] = uu;
r = min(r, k[j].r);
if(find(1) == find(n)) break;
}
}
}
if(find(1) == find(n) && (ansk < r - k[i].l + 1 || (ansk == r - k[i].l + 1 && ansl > k[i].l)))
{
ansk = r - k[i].l + 1;
ansl = k[i].l;
ansr = r;
}
}
printf("%lld\n", ansk);
if(ansk != 0)
for(int i = ansl; i <= ansr; ++i)
printf("%lld%c", i, " \n"[i == ansr]);
return 0;
}
本文来自博客园,作者:蒟蒻orz,转载请注明原文链接:https://www.cnblogs.com/orzz/p/18122114