Codeforces 721C [dp][拓扑排序]
Posted 徐暾
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces 721C [dp][拓扑排序]相关的知识,希望对你有一定的参考价值。
/* 题意:给你一个有向无环图。给一个限定t。 问从1点到n点,在不超过t的情况下,最多可以拜访几个点。 保证至少有一条路时限不超过t. 思路: 1.由无后向性我们可以知道(取决于该图是一个DAG),这题一定可以dp。 2.dp[i][j]代表,到达点i,并且拜访了j个城市的最短时间。 wa点: 没有初始化数组中的0.. */ #include<bits/stdc++.h> #define N 5050 using namespace std; int inf=0x3f3f3f3f; int num[N]; bool vis[N]; int dp[N][N]; struct edge{ int id; int w; edge *next; }; edge edges[N]; edge *adj[N]; int ednum; inline void addedge(int a,int b,int w){ edge *tmp=&edges[ednum++]; tmp->id=b; tmp->w=w; tmp->next=adj[a]; adj[a]=tmp; } int fromx[N][N]; int main() { int n,m,t,a,b,w; scanf("%d%d%d",&n,&m,&t); for(int i=0;i<=n;i++){ for(int j=1;j<=n;j++){ dp[i][j]=inf; } } for(int i=1;i<=m;i++){ scanf("%d%d%d",&a,&b,&w); addedge(a,b,w); num[b]++; } dp[1][1]=0; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(vis[j]||num[j])continue; vis[j]=1; for(edge *it=adj[j];it;it=it->next){ num[it->id]--; for(int k=2;k<=n;k++){ if(dp[it->id][k]>dp[j][k-1]+it->w){ dp[it->id][k]=dp[j][k-1]+it->w; fromx[it->id][k]=j; } } } break; } } for(int i=n;i>=2;i--){ if(dp[n][i]<=t){ printf("%d\n",i); stack<int>ss; int x=n,y=i; ss.push(n); while(fromx[x][y]!=1){ ss.push(fromx[x][y]); x=fromx[x][y]; y--; } ss.push(1); while(!ss.empty()){ int pp=ss.top(); ss.pop(); printf("%d ",pp); } break; } } }
以上是关于Codeforces 721C [dp][拓扑排序]的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #460 (Div. 2)_D. Substring_[dp][拓扑排序]