DP大水题。。关键是路径记录
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int INF=1<<29;
bool vis[105], can[105][105];
int in[105], path[105], dp[105], ro[105], ans;
int main()
{
int t, ri, n, m, a, b, maxv, k, i, j;
scanf("%d",&t);
for(ri=1;ri<=t;ri++)
{
if(ri>1) puts("");
memset(vis,0,sizeof(vis));
memset(can,0,sizeof(can));
memset(path,-1,sizeof(path));
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d",&in[i]);
scanf("%d",&m);
for(i=0;i<m;i++)
{
scanf("%d%d",&a,&b);
if(b==n+1) vis[a]=true;
else can[a][b]=true;
}
dp[1]=0;
path[1]=-1;
for(i=2;i<=n;i++)
{
dp[i]=0;
maxv=-1;
for(j=1;j<i;j++)
{
if(can[j][i]&&maxv<dp[j])
{
maxv=dp[j];
k=j;
}
}
path[i]=k;
if(maxv>=0)
dp[i]=maxv+in[i];
}
ans=-1;
for(i=1;i<=n;i++)
{
if(dp[i]>ans&&vis[i])
{
ans=dp[i];
k=i;
}
}
int ll=0;
for(i=k;i>0;i=path[i])
{
ro[ll++]=i;
}
printf("CASE %d#\n",ri);
printf("points : %d\n",ans);
printf("circuit : ");
for(i=ll-1;i>=0;i--)
printf("%d->",ro[i]);
printf("1\n");
}
return 0;
}