jzoj5177. 【NOIP2017提高組模擬6.28】TRAVEL(二分)
阿新 • • 發佈:2018-11-01
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); }