• 重聚


    自创第一题

    题目背景

    最好的朋友在身边,最爱的人就在对面.

    自爱情公寓拆迁已经过去十多年……

    多年过后,曾经爱情公寓的每个人都成为了自己想成为的样子,一菲成为了著作等身的大教授兼弹一闪道馆馆主,小贤主持的新《你的太阳我的心》大火,咖喱酱成为了娱乐圈配音界的扛把子,子乔和美嘉把事业做大了,成为了人生赢家,海棠成为了一代文豪,大力在火星上研究水稻,张伟则跟随大力成为了火星上有名的大律师。这一天,海棠邀请朋友们来参加掘地重工举办的世界博览会,就这样,大家再一次重聚,踏上了世博会之旅……

    题目描述

    这次博览会一共有(n)个展厅,编号从(1)(n),且这些展厅是由单向道路连接的,掘地重工的工作人员们对这次博览会的路线进行了精心的设计,使得这次博览会的展厅之间不存在循环路线。

    起初,小伙伴们在(1)号展厅,这次旅行的终点在(n)号展览厅---爱情公寓厅,这是掘地重工给爱情公寓的小伙伴们专门准备的礼物。因为他们想要尽快到达(n)号厅而又想尽量多的参观别的展厅,所以他们想在(t)个时间单位内到达(n)号厅。

    假设参观展厅不需要花费时间,现在你的任务就是帮助他们在不超过(t)的时间内确定从(1)号展厅到(n)号展厅的旅程中最多可以参观多少个展厅。保证至少有一条从(1)号展厅到(n)号展厅的路线,并保证这条道路小伙伴们将花费不超过(t)个时间单位通过。

    输入格式

    第一行三个整数(n, m, t),分别表示展厅的数量、展厅之间的道路数量以及时间限制。

    接下来(m)行,每行三个整数(x,y,w),表示从(x)号展厅到(y)号展厅有一条花费时间(w)的路线

    输出格式

    第一行一个整数(ans),表示最多可以参观的展厅数量。

    第二行(ans)个整数,按访问顺序输出路径(即每个访问到的点)

    数据范围

    对于(30%)的数据满足:(2≤n≤10),(1≤m≤10)

    对于(100%)的数据满足:(2≤n≤5000,1≤m≤5000,t≤10^9,1≤w≤10^9)

    (256MB)

    注意

    绝对良心题吧嘻嘻(qwq)

    小清新简单题,用来休闲

    solution

    一句话题意

    有一个(n)个点(m)条边的有向无环图,求从(1)(n)总路径长度不超过(t),且经过点最多的路径。

    题解

    拓扑排序+(DP)

    说实话其实不用给部分分……

    很显然,题目中给出的图是一个(DAG)(有向无环图)

    因为(n)(m)只有(5000),所以我们可以大胆地写一个(O(nm))的算法。

    因为要求最短路径,且图中无环,所以我们可以大胆地(DP)来做

    用一个二维数组(f[i][j])表示从(1)号点到(i)号点经过(j)个点的最短路径(初始化(inf)),最后只要从大到小判断第一个(f[n][i]le t)(i)即可,同时,为了保证每个点都是最小值,(DP)要按照拓扑序的顺序(而不是节点序),因为是(DAG)嘛~

    转移:(f[x][j] = min(f[x][j], f[x][j - 1]+e[i].val))((i)(x)的连边,(j=[2)~(n]))

    再一个问题就是记录路径了,我们可以在(DP)过程中用一个类似于(f)数组的(pre)数组,(pre[i][j])表示从(1)走到(i),经过了(j)个点的上一个节点的编号,输出的时候可以用(stack)记录,也可以直接回溯

    代码

    #include <stack>
    #include <queue> 
    #include <vector>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    const int A = 5e3 + 11;
    const int INF = 0x3f3f3f3f;
    
    inline int read() {
    	char c = getchar(); int x = 0, f = 1;
    	for ( ; !isdigit(c); c = getchar()) if (c == '-') f = -1;
    	for ( ; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
    	return x * f;
    }
    
    int n, m, d, cnt, head[A];
    struct node { int to, nxt, val; } e[A];
    int f[A][A], pre[A][A], rdu[A], mx;;
    vector <int> s;
    stack <int> path;
    
    inline void add(int from, int to, int val) {
        e[cnt].to = to;
        e[cnt].val = val;
        e[cnt].nxt = head[from];
    	head[from] = cnt++;
    }
    
    void topo() {  //拓扑排序
        queue <int> q;
        for (int i = 1; i <= n; i++) if (rdu[i] == 0) q.push(i);
        while (!q.empty()) {
            int x = q.front();
            q.pop();
            s.push_back(x);
            for (int i = head[x]; i != -1; i = e[i].nxt)
        		if ((--rdu[e[i].to]) == 0) q.push(e[i].to);
        }
    }
    
    signed main() {
    	freopen("5.in", "r", stdin);
    	freopen("5.out", "w", stdout);
        memset(f, INF, sizeof(f));
        memset(pre, -1, sizeof(pre));
        memset(head, -1, sizeof(head));
    	n = read(), m = read(), d = read();
        for (int i = 1, x, y, z; i <= m; i++) {
        	x = read(), y = read(), z = read();
            add(x, y, z);
            rdu[y]++;
        }
        topo();
        f[1][1] = 0;
        for (int k = 0; k < s.size(); k++) {
            int x = s[k];
            for (int i = head[x]; i != -1; i = e[i].nxt)
                for (int j = 2; j <= n; j++)
                    if (f[x][j - 1] + e[i].val < f[e[i].to][j]) { 
                        f[e[i].to][j] = f[x][j - 1] + e[i].val;
                        pre[e[i].to][j] = x;
                    }
        }
        for (int i = n; i >= 1; i--)
            if (f[n][i] <= d) {
                mx = i;
                break;
            }
        cout << mx << '
    ';
        int pos = n, dep = mx;
        while (pos != -1) {
            path.push(pos);
            pos = pre[pos][dep];
            dep--;
        }
        while (!path.empty()) {
            cout << path.top() << ' '; 
            path.pop();
        }
    	cout << '
    ';
        return 0;
    }
    
  • 相关阅读:
    Sql Server 2008卸载后再次安装一直报错
    listbox 报错 Cannot have multiple items selected when the SelectionMode is Single.
    Sql Server 2008修改Sa密码
    学习正则表达式
    Sql Server 查询第30条数据到第40条记录数
    Sql Server 复制表
    Sql 常见面试题
    Sql Server 简单查询 异步服务器更新语句
    jQuery stop()用法以及案例展示
    CSS3打造不断旋转的CD封面
  • 原文地址:https://www.cnblogs.com/loceaner/p/12337074.html
Copyright © 2020-2023  润新知