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;
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章