题解-P6005 Time is Mooney G

  • 题目意思

    就是给你一个有向图,你在上面走,没经过一个点可以获得,最后你要减去(走过的边数)

  • 考虑,我们设表示第天到达城市的最大收益。

    转移很简单

    对于的处理我们只需要反向建有向边即可,答案就是

    但是这样的枚举范围无法确定,但是我们发现即可,因为

#include <bits/stdc++.h>
using namespace std;

const int N=1005;

int n,m,C,cnt,head[N];
int M[N],f[N][N],ans; 

struct nood {
    int nex,to;
};
nood e[N<<2];

inline void jia(int u,int v) {
    e[++cnt].nex=head[u];
    head[u]=cnt;
    e[cnt].to=v;
}

inline int read() {
    int sum=0; char ch=getchar();
    while(!isdigit(ch)) ch=getchar();
    while(isdigit(ch)) 
        sum=sum*10+(ch^48),ch=getchar();
    return sum;
}

int main() {
    n=read();
    m=read();
    C=read();
    for ( int i=1;i<=n;i++ ) M[i]=read();
    for ( int i=1;i<=m;i++ ) {
        int u,v;
        u=read();
        v=read();
        jia(v,u);
    }
    //f[i][j]表示第i天到达第j座城市的最大收益
    memset(f,-1,sizeof(f));
    f[0][1]=0;
    for ( int i=1;i<=1000;i++ ) {
        for ( int j=1;j<=n;j++ )
            for ( int k=head[j];k;k=e[k].nex ) {
                int v=e[k].to;
                if(~f[i-1][v]) 
                    f[i][j]=max(f[i][j],f[i-1][v]+M[j]);
            }
        if(ans<f[i][1]-C*i*i) ans=f[i][1]-C*i*i;
    }
    printf("%d\n",ans);
    return 0;
}