HDU 1224 Free DIY Tour 距离的更新 bellman-Ford变形 dp ***

点击打开链接

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


你可能感兴趣的:(HDU 1224 Free DIY Tour 距离的更新 bellman-Ford变形 dp ***)