zoukankan      html  css  js  c++  java
  • Codeforces 721C [dp][拓扑排序]

    /*
    题意:给你一个有向无环图。给一个限定t。
    问从1点到n点,在不超过t的情况下,最多可以拜访几个点。
    保证至少有一条路时限不超过t.
    思路:
    1.由无后向性我们可以知道(取决于该图是一个DAG),这题一定可以dp。
    2.dp[i][j]代表,到达点i,并且拜访了j个城市的最短时间。
    wa点:
    没有初始化数组中的0..
    */
    
    #include<bits/stdc++.h>
    #define N 5050
    using namespace std;
    int inf=0x3f3f3f3f;
    int num[N];
    bool vis[N];
    int dp[N][N];
    struct edge{
        int id;
        int w;
        edge *next;
    };
    edge edges[N];
    edge *adj[N];
    int ednum;
    inline void addedge(int a,int b,int w){
        edge *tmp=&edges[ednum++];
        tmp->id=b;
        tmp->w=w;
        tmp->next=adj[a];
        adj[a]=tmp;
    }
    int fromx[N][N];
    int main()
    {
        int n,m,t,a,b,w;
        scanf("%d%d%d",&n,&m,&t);
        for(int i=0;i<=n;i++){
            for(int j=1;j<=n;j++){
                dp[i][j]=inf;
            }
        }
        for(int i=1;i<=m;i++){
            scanf("%d%d%d",&a,&b,&w);
            addedge(a,b,w);
            num[b]++;
        }
        dp[1][1]=0;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                if(vis[j]||num[j])continue;
                vis[j]=1;
                for(edge *it=adj[j];it;it=it->next){
                    num[it->id]--;
                    for(int k=2;k<=n;k++){
                        if(dp[it->id][k]>dp[j][k-1]+it->w){
                            dp[it->id][k]=dp[j][k-1]+it->w;
                            fromx[it->id][k]=j;
                        }
                    }
                }
                break;
            }
        }
    
        for(int i=n;i>=2;i--){
            if(dp[n][i]<=t){
                printf("%d
    ",i);
                stack<int>ss;
                int x=n,y=i;
                ss.push(n);
                while(fromx[x][y]!=1){
                    ss.push(fromx[x][y]);
                    x=fromx[x][y];
                    y--;
                }
                ss.push(1);
                while(!ss.empty()){
                    int pp=ss.top();
                    ss.pop();
                    printf("%d ",pp);
                }
                break;
            }
        }
    
    }
  • 相关阅读:
    Leetcode Binary Tree Level Order Traversal
    Leetcode Symmetric Tree
    Leetcode Same Tree
    Leetcode Unique Paths
    Leetcode Populating Next Right Pointers in Each Node
    Leetcode Maximum Depth of Binary Tree
    Leetcode Minimum Path Sum
    Leetcode Merge Two Sorted Lists
    Leetcode Climbing Stairs
    Leetcode Triangle
  • 原文地址:https://www.cnblogs.com/tun117/p/5925471.html
Copyright © 2011-2022 走看看