(DAGdp)洛谷P1137旅行计划

tech2024-12-25  21

洛谷P1137旅行计划

思路:

题目说只能走到东边的城市,又保证 x x x y y y的西面,虽然说是双向道路,但是就可以直接建 ( x , y ) (x,y) (x,y)的边。 可以得到 d p [ v ] = max ⁡ ( d p [ v ] , d p [ u ] + 1 ) dp[v]=\max(dp[v],dp[u]+1) dp[v]=max(dp[v],dp[u]+1),那么怎么解决后效性呢?就是用拓扑排序,因为拓扑排序出来的点就可以保证一个点不会再有入度,这样就不会受到别的点的影响,这样就没有了后效性。

代码:

#include<bits/stdc++.h> #define pii pair<int,int> #define ll long long #define cl(x,y) memset(x,y,sizeof(x)) #define ct cerr<<"Time elapsed:"<<1.0*clock()/CLOCKS_PER_SEC<<"s.\n"; #define mp make_pair #define pb push_back #define fi first #define se second #define all(x) x.begin(),x.end() #define lson x<<1,l,mid #define rson x<<1|1,mid+1,r #define INF 1e18 const int N=1e6+10; const int mod=1e9+7; const int inf=0x3f3f3f3f; const double eps=1e-8; const double pi=acos(-1); using namespace std; struct edge { int u,v; }e[N]; int head[N]={0},len=0,in[N]={0},dp[N]={0}; void add(int u,int v) { e[++len]={head[u],v}; head[u]=len; } int main() { ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); int n,m,i; cin>>n>>m; for(i=1;i<=m;i++) { int u,v; cin>>u>>v; add(u,v); in[v]++; } queue<int> q; for(i=1;i<=n;i++) if(!in[i]) q.push(i); while(!q.empty()) { int u=q.front(); q.pop(); for(i=head[u];i;i=e[i].u) { int v=e[i].v; dp[v]=max(dp[u]+1,dp[v]); in[v]--; if(!in[v]) q.push(v); } } for(i=1;i<=n;i++) cout<<dp[i]+1<<endl; return 0; }
最新回复(0)