codeforces 721C
题意:一个n个点,m条边的无环无重边有向图,经过第i条路径需花费时间ti,要求你选一条从1到n的路径,使得经过的不同城市最多,并且总时间小于等于t。
题解:很简单的一道dp,考试的时候没想出来,一通乱搞,最后跑去A了D题。
dp[i][j]表示第i个点,已经经过了j个点的最小时间,按照拓扑序搞一搞即可。
1 #include<bits/stdc++.h> 2 #define maxn 5005 3 #define inf 2000000000 4 using namespace std; 5 int dp[maxn][maxn],fr[maxn][maxn],cnt,n,m,t,head[maxn],tup[maxn],q[maxn],num; 6 struct edge{int to,next,v;}e[2*maxn]; 7 void ins(int u,int v,int val){ 8 e[++cnt].to=v;e[cnt].next=head[u];head[u]=cnt;e[cnt].v=val; 9 } 10 void dfs(int k){ 11 for(int i=head[k];i;i=e[i].next){ 12 tup[e[i].to]--; 13 for(int j=1;j<=n;j++){ 14 if(dp[k][j]<=t&&dp[e[i].to][j+1]>dp[k][j]+e[i].v) { 15 dp[e[i].to][j+1]=dp[k][j]+e[i].v; 16 fr[e[i].to][j]=k; 17 } 18 } 19 if(tup[e[i].to]==0) dfs(e[i].to); 20 } 21 } 22 int main(){ 23 scanf("%d%d%d",&n,&m,&t);int a,b,c; 24 for(int i=1;i<=m;i++){ 25 scanf("%d%d%d",&a,&b,&c); 26 ins(a,b,c); 27 tup[b]++; 28 } 29 for(int i=1;i<=n;i++) 30 for(int j=1;j<=n;j++) dp[i][j]=t+1; 31 dp[1][1]=0; 32 for(int i=1;i<=n;i++){ 33 if(tup[i]==0){ 34 dfs(i); 35 } 36 }dp[n][0]=0; 37 for(int i=n;i>=0;i--){ 38 if(dp[n][i]<=t){ 39 printf("%d\n",i);num=i; 40 for(int poi=n;poi!=1;poi=fr[poi][num]){ 41 q[num]=poi;num--; 42 } 43 num=i; 44 break; 45 } 46 }printf("1"); 47 for(int i=2;i<=num;i++) printf(" %d",q[i]);printf("\n"); 48 return 0; 49 }