zoukankan      html  css  js  c++  java
  • Power OJ 2605 SPFA+dp思想

    题目链接【https://www.oj.swust.edu.cn/problem/show/2605】

    题意:给出包含N(N <= 5000)个点M条边的有向图,然后求1 - N在满足距离小于T的情况下,最多走多少个点。

    题解:dp[i][j]表示邹大鹏i点,经过了j个点的最短路。用pre维护一下路径即可。

    #include<bits/stdc++.h>
    using namespace std;
    typedef pair<int, int> Pair;
    const int INF = 1e9 + 15;
    const int maxn = 5050;
    int N, M, T;   
    struct Edge
    {
        int to, next, len;
        Edge() {}
        Edge(int to, int next, int len): to(to), next(next), len(len) {}
    } E[maxn*maxn];
    int head[maxn], tot;
    void initEdge()
    {
        for(int i = 0; i <= N; i++) head[i] = -1;
        tot = 0;
    }
    void addEdge(int u, int v, int len)
    {
        E[tot] = Edge(v, head[u], len);
        head[u] = tot++;
    }
    int dp[maxn][maxn], pre[maxn][maxn], in[maxn][maxn];
    void Spfa()
    {
        queue<Pair>que;
        dp[1][1] = 0;
        que.push(make_pair(1, 1));
        in[1][1] = 1;
        while(!que.empty())
        {
            int u = que.front().first;
            int num = que.front().second;
            que.pop();
            in[u][num] = 0;
            for(int k = head[u]; ~k; k = E[k].next)
            {
                int v = E[k].to;
                if(dp[v][num + 1] > dp[u][num] + E[k].len)
                {
                    dp[v][num + 1] = dp[u][num] + E[k].len;
                    pre[v][num + 1] = u;
                    if(!in[v][num + 1])
                    {
                        que.push(make_pair(v, num + 1));
                        in[v][num + 1] = 1;
                    }
                }
            }
        }
    }
    int main ()
    {
        while(~scanf("%d %d %d", &N, &M, &T))
        {
            initEdge();
            for(int i = 1; i <= M; i++)
            {
                int u, v, len;
                scanf("%d %d %d", &u, &v, &len);
                addEdge(u, v, len);
            }
            for(int i = 1; i <= N; i++)
                for(int j = 1; j <= N; j++)
                    dp[i][j] = INF, pre[i][j] = in[i][j] = 0;
            Spfa();
            int ans = N;
            for(; ans >= 1; ans--)
                if(dp[N][ans] <= T) break;
            vector<int>vt;
            int u = N, num = ans;
            while(pre[u][num])
            {
                int v = pre[u][num];
                vt.push_back(v);
                u = v;
                num--;
            }
            printf("%d
    %d
    ", dp[N][ans], ans);
            int sz = vt.size() - 1;
            for(int i = sz; i >= 0; i--)
                printf("%d ", vt[i]);
            printf("%d
    ", N);
        }
        return 0;
    }
    

      

  • 相关阅读:
    Linux 磁盘分区
    curl
    Metasploit ms10_046_shortcut_icon_dllloader 利用
    Ettercap 入门
    Ettercap dos_attack
    Centos7/Debian 配置双网卡
    Centos7配置单网卡,多IP
    Ettercap MITM Arp Poisoning
    Ettercap DNS Spoofing
    java常用设计模式--工厂模式简单例子
  • 原文地址:https://www.cnblogs.com/pealicx/p/7631322.html
Copyright © 2011-2022 走看看