题目大意:给出一些城市的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;
}