版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhanghaoxian1/article/details/83349610
5177. 【NOIP2017提高组模拟6.28】TRAVEL
Description
Input
Output
Sample Input
4 4
1 2 1 10
2 4 3 5
1 3 1 5
2 4 2 7
Sample Output
6
2 3 4 5 6 7
分析:枚举区间起点,二分终点,然后每条边都走一次判断是否能走到n。
代码
#pragma optimize(2)
#include <cstdio>
#include <algorithm>
#define N 10000
using namespace std;
struct arr
{
int l,r,nxt,to,num;
}a[N];
struct node
{
int l,r,x,y;
}b[N];
int n,m,tot,p,ls[N],v[N];
bool fl;
int cmp(node i, node j){return i.r < j.r;}
inline void add(int x, int y, int l, int r, int i)
{
a[++tot].to = y;
a[tot].nxt = ls[x];
a[tot].l = l;
a[tot].r = r;
a[tot].num = i;
ls[x] = tot;
}
inline int read() {
char ch = getchar(); int x = 0, f = 1;
while(ch < '0' || ch > '9') {
if(ch == '-') f = -1;
ch = getchar();
} while('0' <= ch && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
} return x * f;
}
inline void dfs(int x, int L, int R)
{
if (fl) return;
if (x == n){fl = true; return;}
for (int i = ls[x]; i; i = a[i].nxt)
if (v[a[i].num] != p && a[i].l <= L && a[i].r >= R)
{
v[a[i].num] = p;
dfs(a[i].to, L, R);
}
}
int main()
{
int I, J;
scanf("%d%d", &n, &m);
for (int i = 1; i <= m; i++)
{
int l,r,x,y;
x=read(),y=read(),l=read(),r=read();
add(x, y, l, r, i);
add(y, x, l, r, i);
b[i].x = x;
b[i].y = y;
b[i].l = l;
b[i].r = r;
}
sort(b + 1, b + m + 1, cmp);
int ans = 0;
for (int i = 1; i <= m; i++)
{
int L = 1, R = m, j = 0;
while (L <= R)
{
int mid = (L + R) / 2;
fl = false;
p++;
dfs(1, b[i].l, b[mid].r);
if (fl) j = mid, L = mid + 1;
else R = mid - 1;
}
if (b[j].r - b[i].l + 1 > ans)
{
ans = b[j].r - b[i].l + 1;
J = b[j].r;
I = b[i].l;
}
if (b[j].r - b[i].l + 1 == ans) if (b[i].l < I) I = b[i].l, J = b[j].r;
}
printf("%d\n", ans);
if (ans)
for (int i = I; i <= J; i++) printf("%d ", i);
}