在网格图上,以(x , y) 代表在y时刻,在第x个位置 那么很显然,你把关闭的闸门在图上表示出来就可以了 复杂度 O ( n ∗ m a x ( C ) ) O(n * max(C)) O(n∗max(C))
发现暴力做法的瓶颈在于 m a x ( C ) max(C) max(C)上,考虑怎么搞掉
于是大胆的猜想,跟缝有没有关系
我们可以用跑最短路的思想来处理 对于两个相邻的缝 ,能否到达对方(非常容易判断,不再赘述) 那么直接按照堆优化的disjkra跑一下就可以了 复杂度 O ( m ∗ l o g m ) O(m * logm) O(m∗logm)
#include<bits/stdc++.h> #define MAXN 200005 typedef long long ll; using namespace std; int n,m; ll ans,tot,vis[MAXN],f[MAXN]; struct node{ll dx,L,R,val,id;}t[MAXN]; struct node2{ll id,val;}; vector<node>ycl[MAXN]; vector<int>ycl2[MAXN]; bool cmp(node x , node y){return x.L < y.L;} bool cmp2(node x , node y){ if(x.R == y.R){ if(x.L == y.L)return x.dx < y.dx; return x.L < y.L; } return x.R < y.R; } bool operator < (node2 x , node2 y){return x.val > y.val;} priority_queue<node2>q2; int main(){ cin>>n>>m;ll a,b,c;ans = 0x3f3f3f3f3f3f; for(int i = 1 ; i <= m ; i++){ cin>>a>>b>>c; ycl[a].push_back((node){a , b , c , 0 , 0}); } for(int i = 1 ; i <= n ; i++)sort(ycl[i].begin() , ycl[i].end() , cmp); ll last = 0 , zz; for(int i = 1 ; i <= n + 1 ; i++){ zz = ycl[i].size(); if(zz == 0){ tot++ , t[tot].dx = i; t[tot].L = 0 , t[tot].R = 0x3f3f3f3f3f3f; continue; } last = 0; for(int j = 0 ; j < zz ; j++){ tot++ , t[tot].dx = i; t[tot].L = last , t[tot].R = ycl[i][j].L - 1; last = ycl[i][j].R + 1; } tot++ , t[tot].dx = i; t[tot].L = last , t[tot].R = 0x3f3f3f3f3f3f; } memset(f , 0x3f , sizeof(f)); sort(t + 1 , t + 1 + tot , cmp2); t[0].L = 0 , t[0].R = 0x3f3f3f3f3f3f , t[0].dx = 0 , t[0].val = f[0] = 0; tot++ , t[tot].L = 0 , t[tot].R = 0x3f3f3f3f , t[tot].dx = n + 1 , t[tot].val = f[tot] = 0x3f3f3f3f3f3f; for(int i = 0 ; i <= tot ; i++)ycl2[t[i].dx].push_back(i); q2.push((node2){0 , 0}); node2 now;ll zz2,pp; while(!q2.empty()){ now = q2.top();q2.pop(); if(vis[now.id])continue; vis[now.id] = 1; if(t[now.id].dx > 0){ zz2 = ycl2[t[now.id].dx - 1].size(); for(int i = 0 ; i < zz2 ; i++){ pp = ycl2[t[now.id].dx - 1][i]; if(abs(t[now.id].dx - t[pp].dx) != 1)continue; if(t[now.id].L + 1 > t[pp].R)continue; if(t[now.id].R + 1 < t[pp].L)continue; if(now.val + 1 > t[pp].R)continue; zz = max(f[now.id] + 1 , t[pp].L); if(zz >= f[pp])continue; f[pp] = zz; q2.push((node2){pp , f[pp]}); } } if(t[now.id].dx < n + 1){ zz2 = ycl2[t[now.id].dx + 1].size(); for(int i = 0 ; i < zz2 ; i++){ pp = ycl2[t[now.id].dx + 1][i]; if(abs(t[now.id].dx - t[pp].dx) != 1)continue; if(t[now.id].L + 1 > t[pp].R)continue; if(t[now.id].R + 1 < t[pp].L)continue; if(now.val + 1 > t[pp].R)continue; zz = max(f[now.id] + 1 , t[pp].L); if(zz >= f[pp])continue; f[pp] = zz; q2.push((node2){pp , f[pp]}); } } } if(f[tot] >= 0x3f3f3f3f3f)cout<<-1<<endl; else cout<<f[tot]<<endl; }