洛谷 - P1434 - 滑雪 - 有向圖最長鏈
阿新 • • 發佈:2019-04-05
col pri main urn 滑雪 return def scan pos
https://www.luogu.org/problemnew/show/P1434
有向圖的最長鏈怎麽求?有環肯定不行,這裏保證無環。(否則應該使用toposort先求出所有不帶環的位置)
設dp[u]=以u點開始的最長鏈的長度,那麽以u為子節點的v就有dp[v]=max(dp[v],dp[u]+1),遍歷其每個子節點就可以得知其最長鏈。
所以最簡單的方法其實是記憶化搜索。
第一次完全手寫前向星版本的dfs。
#include<bits/stdc++.h> using namespace std; #define ll long long int g[105][105];int head[10005]; struct Edge{ int v,nxt; Edge(int v=0,int nxt=0):v(v),nxt(nxt){} }edge[10005*4]; int indeg[10005]; int etop=0; void addedge(int u,int v){ edge[etop].v=v; edge[etop].nxt=head[u]; indeg[v]++; head[u]=etop++; } int n,m; int dp[10005]; int dfs(int id){if(dp[id]!=-1) return dp[id]; else{ int res=0; for(int i=head[id];i!=-1;i=edge[i].nxt){ res=max(res,dfs(edge[i].v)); } res++; return dp[id]=res; } } int main(){ scanf("%d%d",&n,&m); memset(g,0x3f,sizeof(g)); memset(head,-1,sizeof(head)); memset(dp,-1,sizeof(dp)); for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ scanf("%d",&g[i][j]); } } for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ if(g[i][j]>g[i-1][j]){ addedge((i-1)*m+j,(i-2)*m+j); } if(g[i][j]>g[i+1][j]){ addedge((i-1)*m+j,(i)*m+j); } if(g[i][j]>g[i][j-1]){ addedge((i-1)*m+j,(i-1)*m+j-1); } if(g[i][j]>g[i][j+1]){ addedge((i-1)*m+j,(i-1)*m+j+1); } } } int ans=0; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ if(indeg[(i-1)*m+j]==0){ ans=max(ans,dfs((i-1)*m+j)); } } } printf("%d\n",ans); }
洛谷 - P1434 - 滑雪 - 有向圖最長鏈