点击打开链接
题目大意:给出一些城市的point,从起点出发经过一些城市最终回到起点,在这个过程中经过的下一个城市的point值要求不低于现在城市的point值(最后回到城市1的情况不算),问最后能够达到的最大point值之和,并输出路径。
#include<bits/stdc++.h> #define INF 0x3f3f3f3f #define M 100001 using namespace std; int n,Map[1000][1000],a[1000],dp[1000]; int pre[1000]; int path(int flag) ///利用栈输出元素 { if(flag==-1) return 0; path(pre[flag]); printf("%d->",flag); } void floyd() { for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) { /// 这种方法也可以 /// if(Map[i][j]&&dp[j]<=dp[i]+a[i]) ///为了处理当某一点的数值为0时仍然可以把该点加上 /// ///(虽然a[i]==0dp[i]+a[i]仍然可以表示与j连接的最大距离,防止存在k与j连接,必须通过j与i相连才可以达到最大) /// { /// dp[j]=dp[i]+a[i]; /// pre[j]=i; /// } if(Map[j][i]&&dp[i]<=dp[j]+a[j]) ///逐渐更新dp[i]的权值使他保持最大 { dp[i]=dp[j]+a[j]; pre[i]=j; } } } printf("points : %d\n",dp[n]); printf("circuit : "); path(pre[n]); puts("1"); } int main() { int T,m,u,v,cas=1; scanf("%d",&T); while(T--) { if(cas!=1) puts(""); scanf("%d",&n); for(int i=1; i<=n; i++) scanf("%d",&a[i]); n=n+1; ///1 与 n+1 是相同地址 memset(Map,0,sizeof(Map)); memset(dp,0,sizeof(dp)); memset(pre,-1,sizeof(pre)); scanf("%d",&m); for(int j=1; j<=m; j++) { scanf("%d%d",&u,&v); Map[u][v]=1; } printf("CASE %d#\n",cas++); floyd(); } return 0; }