1. 程式人生 > >luoguP1137 旅行計劃(記憶化搜尋&拓撲排序+dp)

luoguP1137 旅行計劃(記憶化搜尋&拓撲排序+dp)

題目連結

記憶化搜尋

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
const int maxn=200005;
int n,m;
int head[maxn],to[2*maxn],nex[2*maxn],cnt=0;
queue<int> q;
void add(int u,int v)
{
	nex[++cnt]=head[u];
	to[cnt]=v;
head[u]=cnt; } int in[100005],ans[100005],dp[100005]; int num=0; int dfs(int u) { if(dp[u]) return dp[u];//優化,不加會t dp[u]=1; for(int i=head[u];i;i=nex[i]) { dp[u]=max(dp[u],dfs(to[i])+1); } return dp[u]; } int main() { scanf("%d%d",&n,&m); int u,v; for(int i=1;i<=m;i++) { scanf("%d%d",&
u,&v); add(v,u); } for(int i=1;i<=n;i++) printf("%d\n",dfs(i)); }

拓撲排序+dp

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
const int maxn=200005;
int n,m;
int head[maxn],to[2*maxn],nex[2*maxn],cnt=0;
queue<
int> q; void add(int u,int v) { nex[++cnt]=head[u]; to[cnt]=v; head[u]=cnt; } int in[100005],ans[100005],dp[100005]; int num=0; void topo() { for(int i=1;i<=n;i++) { if(in[i]==0) q.push(i); } while(!q.empty()) { int u=q.front(); q.pop(); ans[++num]=u; for(int i=head[u];i;i=nex[i]) { in[to[i]]--; if(in[to[i]]==0) q.push(to[i]); } } } int main() { scanf("%d%d",&n,&m); int u,v; for(int i=1;i<=m;i++) { scanf("%d%d",&u,&v); add(u,v); in[v]++; } topo(); for(int i=1;i<=n;i++) dp[i]=1; for(int i=1;i<=n;i++) { int u=ans[i]; for(int j=head[u];j;j=nex[j]) { dp[to[j]]=max(dp[to[j]],dp[u]+1); } } for(int i=1;i<=n;i++) printf("%d\n",dp[i]); }