hdu Instrction Arrangement(关键路径 + 拓扑排序)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586

题意:

5 2                     //5个进程(编号从 0 开始)需要被执行,有2个约束条件, 问全部执行完成的最短时间。

1 2 1                   //1号要在2号进程执行完成的后一纳秒执行

3 4 1

Sample Output

2

关键路径:

  基于AOE网(Activity On Edge),也就是说,每一条边代表着一个事件的发生,边的权值即为事件的花费时间。

节点可以抽象理解为一个状态。在拓扑序列中,后面的状态是由前面的状态经过事件的发生(边)到达的,从 0 节点(什么都没做)到 n - 1 (完成 n 个事件)的状态。

关键路径是由关键节点组成的路径,关键路径上所需时间为完成这个工程(n 个事件)最少花费时间。

可以用来解决的问题:eg,有一项工程,工程有 n 个事件,有些可以同步发生,而有些有先后执行的顺序限制, 问完成工程的最少时间?

关键节点:

  要想在最短时间完成工程,那么关键节点的最早发生时间和最晚发生时间是相同的。这需要正反两次拓扑排序。

思路:

  这道题只需要正向拓扑排序,求出关键路径上所需时间即可。

  对于输入:

    5 3

    0 1 3

    1 2 4    //可以理解为从 2 号状态(已经完成了事件 2 和事件 0 的状态)花费间隔 3 纳秒,可以到达 1 状态。

    3 4 3

#include <stdio.h>
#include <queue>
#include <math.h>
#include <string.h>
#include <algorithm>
using namespace std;

const int N = 1007;

typedef struct Edge
{
    int w;
    int to;
    int next;
}edge;
edge eg[N * 10];

int n, m, head[N], isVis[N], in[N], out[N], val[N];  //val记录每个状态的时间,记录到达当前状态最长的时间
queue <int> q;

int criticalPath()
{
    int max = -1;
    while (!q.empty())
        q.pop();
    memset(val, 0, sizeof(val));
    for (int i = 0; i < n; i++)
    {
        if (!in[i])
        {
            val[i] = 1;
            q.push(i);
            isVis[i] = 1;
        }
    }
    while (!q.empty())
    {
        int temp = q.front();
        q.pop();
        if (val[temp] > max)
            max = val[temp];
        int r = head[temp];
        while (r != -1)
        {
            in[eg[r].to]--;
            if (val[eg[r].to] < val[temp] + eg[r].w - 1)
                val[eg[r].to] = val[temp] + eg[r].w - 1;
            if (!in[eg[r].to] && !isVis[eg[r].to])
            {
                val[eg[r].to]++;
                isVis[eg[r].to] = 1;
                q.push(eg[r].to);
            }
            r = eg[r].next;
        }
    }
    return max;
}

int main()
{
    while (scanf("%d%d", &n, &m) != EOF)
    {
        memset(isVis, 0, sizeof(isVis));
        memset(head, -1, sizeof(head));
        for (int i = 1; i <= m; i++)
        {
            int u, v, w;
            scanf("%d%d%d", &v, &u, &w);
            eg[i].to = v;
            eg[i].w = w;
            in[v]++;
            out[u]++;
            eg[i].next = head[u];
            head[u] = i;
        }
        printf("%d\n", criticalPath());
    }
    return 0;
}
时间: 2024-10-29 00:11:20

hdu Instrction Arrangement(关键路径 + 拓扑排序)的相关文章

hdu 4857 逃生 (拓扑排序+保证最小在前面)

逃生 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 74    Accepted Submission(s): 13 Problem Description 糟糕的事情发生啦,现在大家都忙着逃命.但是逃命的通道很窄,大家只能排成一行. 现在有n个人,从1标号到n.同时有一些奇怪的约束条件,每个都形如:a必须在b之前. 同时,社会是不平

HDU 4324:Triangle LOVE( 拓扑排序 )

Triangle LOVE Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 2271    Accepted Submission(s): 946 Problem Description Recently, scientists find that there is love between any of two people. For

HDU 4857 (反向拓扑排序 + 优先队列)

题意:有N个人,M个优先级a,b表示a优先于b,并且每个人有个编号的优先级,输出顺序. 思路来自:与PKU3687一样 在基本的拓扑排序的基础上又增加了一个要求:编号最小的节点要尽量排在前面:在满足上一个条件的基础上,编号第二小的节点要尽量排在前面:在满足前两个条件的基础上,编号第三小的节点要尽量排在前面--依此类推.(注意,这和字典序是两回事,不可以混淆.) 如图 1 所示,满足要求的拓扑序应该是:6 4 1 3 9 2 5 7 8 0. 图 1 一个拓扑排序的例子 一般来说,在一个有向无环图

hdu 4857 逃生(拓扑排序逆序 + 优先队列)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4857 题意:有编号 1 - n 的 n 个人逃生,编号越小的人越有钱, 在满足 m 个前提的条件下要尽可能早的逃脱 .m个前提,对于每个前提 a , b,代表 a 要早于 b逃脱. 思路: (1)这题可以理解为有钱的人优先级越高,所以可以用优先队列. (2)但是要注意这道题和字典序升序的区别. eg:5 1 5 1 按照字典序的答案:2 3 4 5 1,    本题答案: 5 1 2 3 4. 因为

HDU 5438 Ponds (拓扑排序+DFS)2015 ACM/ICPC Asia Regional Changchun Online

[题目链接]:click here~~ [题目大意]: 题意:在一个无向图中有 p 个点, m 条边,每个点有一个值 vi .不断的删去度数小于2的点直到不能删为止.求新图中所有点个数为奇数的连通分量的点值的和. 1<p<10^4,1<m<10^5 [思路]删边考虑类似拓扑排序的写法,不过topsort是循环一遍1到n结点入度为0的结点,然后加入到队列中,这里只要改一下度数小于等于1,最后DFS 判断一下 挫挫的代码: /* * Problem: HDU No.5438 * Run

HDU 4857 逃生(拓扑排序逆向+邻接表存图)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4857 题目: Problem Description 糟糕的事情发生啦,现在大家都忙着逃命.但是逃命的通道很窄,大家只能排成一行. 现在有n个人,从1标号到n.同时有一些奇怪的约束条件,每个都形如:a必须在b之前.同时,社会是不平等的,这些人有的穷有的富.1号最富,2号第二富,以此类推.有钱人就贿赂负责人,所以他们有一些好处. 负责人现在可以安排大家排队的顺序,由于收了好处,所以他要让1号尽量靠前,

hdu 4857 逃生 (拓扑排序+优先队列)

逃生 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 688    Accepted Submission(s): 190 Problem Description 糟糕的事情发生啦,现在大家都忙着逃命.但是逃命的通道很窄,大家只能排成一行. 现在有n个人,从1标号到n.同时有一些奇怪的约束条件,每个都形如:a必须在b之前.同时,社会是不平

hdu 4857 逃生(拓扑排序)

本题链接:点击打开链接 本题大意: 输入一个T,表示有T组测试输出:然后输入和M,表示有N个点,M条有向边,然后输入每条边的两个点a,b:表示a必须在b前:输出一种符合要求的拓扑序列. 解题思路: 最先输出的是排在最前面的,所以我想的是输入a,b,将b入度自加,然后用拓扑排序,从小到大进行查找,先找到的入度为零的点就输出,然后更新各点.因为本题范围要求比较大,所以就不能使用二维数组来建图,要使用链表.但我也不清楚发生了什么,按照这样的思路得到的答案是错误的,参考别人的代码,发现别人都是反向建图,

HDU 4324-- Triangle LOVE【拓扑排序 &amp;&amp; 邻接表实现】

Triangle LOVE Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 3496    Accepted Submission(s): 1357 Problem Description Recently, scientists find that there is love between any of two people. Fo