CodeForces 721C

问题描述CodeForces 721C

思路这是一个拓扑图,询问从1到n在T时间内最多能观光几个景点,并输出顺序,有边权。
这题是一个拓扑dp,考虑dp[i][j],到达i点时,观光了j个景点的最小时间
转移是这样对于一条边u -> v,dp[v][j] = min(dp[v][j],dp[u][j – 1] + dis[u][v]);

当时不会保存多个点的情况,用dp保存即可。

AC代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <math.h>
#include <string.h>
#include <queue>
#include <set>
#include <map>
#include <algorithm>
using namespace std;

const int maxn=5005;
const int inf=0x3f3f3f3f;
//int dis[maxn][maxn];
int vin[maxn];
struct edge
{
    int v;
    int cost;
    edge(int a,int b)
    {
        v=a,cost=b;
    }
};
typedef vector<edge> vec;
vec e[maxn];
int n,m,t;
struct node
{
    int per;
    int use;
} dp[maxn][maxn];
void tp()
{
    queue<int>q;
    for(int i=1; i<=n; i++)
        if(vin[i]==0)
            q.push(i);
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        for(int i=0; i<e[u].size(); i++)
        {
            int v=e[u][i].v;
            int cost=e[u][i].cost;
            vin[v]–;
            if(vin[v]==0)
                q.push(v);
            for(int j=1; j<=n; j++)
                if(dp[v][j].use>dp[u][j-1].use+cost)
                {
                    dp[v][j].use=dp[u][j-1].use+cost;
                    dp[v][j].per=u;
                }
        }
    }
}
void show(int i,int j)
{
    if(dp[i][j].per==-1)
    {
        printf(“1 “);
        return;
    }
    show(dp[i][j].per,j-1);
    printf(“%d “,i);
}
int main()
{
    //freopen(“intput.txt”,”r”,stdin);
    cin>>n>>m>>t;
    int a,b,c;
    for(int i=0; i<=n; i++)
        for(int j=0; j<=n; j++)
        {
            dp[i][j].use=inf;
        }
    memset(vin,0,sizeof(vin));
    for(int i=0; i<m; i++)
    {
        scanf(“%d%d%d”,&a,&b,&c);
        e[a].push_back(edge(b,c));
        vin[b]++;
    }
    //fill(tp,tp+maxn*maxn-1,inf);
    dp[1][1].use=0;
    dp[1][1].per=-1;
    tp();
    //for(int i=0;i<k;i++)cout<<topu[i]<<‘ ‘;
    //cout<<endl;
    for(int i=n; i>=1; i–)
    {
        if(dp[n][i].use<=t)
        {
            printf(“%d\n”,i);
            show(n,i);
            return 0;
        }
    }
    return 0;
}



点赞