Instrction Arrangement[hdu4109][拓扑排序+dp]

摘要:
输出输出一个整数,这是CPU需要运行的最短时间。样本521213412分析了y必须在x之后的秒内执行的约束。同时,y可以包含在多组约束中。将约束视为单向边,所有约束将形成一个图,因为如果y在x后面,y就不能有一条边连接到x,而整个图是DAG,可以拓扑排序。定义dp[i],它表示执行指令i的最早时间,那么dp[i]=max,A[j][i]表示我必须执行#include 在j执行后的[j][i]秒内使用namespacestd;组分最大值=10005;堆栈<int>stk;结构边{intto,nx,w;}e[maxn];intn,m,len,ans=1,head[maxn],rd[maxn],dp[maxn';Void insert{//insert e[++len].to=y;e[len].nx=head[x];e[len].w=w;head[x]=len;}Void kahn(){//kahn算法堆栈<int>stk;forif(!stk.empty()){intu=stk.top();//取出堆栈顶部穿透为0的点stk.pop();对于{intv=e[i].to,w=e[i].w;rd[v]--;dp[v]=max;/如果有多个限制,最远的ans=max;If(!这是一个很好的例子!
Instrction Arrangement(hdu4109)[拓扑排序+dp]

Description

n个指令m个要求 例如 X,Y,Z 代表 指令Y必须在指令XZ秒执行 输出cpu运行的最小时间运行最小时间 也就是要满足最大的时间要求

input

输入由多个测试用例组成
第一行有两个整数 N,M (N <= 1000,M <= 10000),表示存在 N 指令和 M 依赖关系。
以下 M 行包含三个整数 X、Y、Z,表示 X 和 Y 之间的安全距离为 Z,Y 应在 X 之后运行。指令编号为 0 到 N - 1。

output

打印一个整数,这是 CPU 需要运行的最短时间。

Sample

5 2
1 2 1
3 4 1
2

分析

限制条件是 y 必须在 x 后多少秒执行,同时一个y可能包含在多组限制条件里,把限制条件当成一条单向边,所有限制条件会构成一张图

因为如果 y 在 x 后,y就不可能有一条边连到x前,整张图就是DAG,可以拓扑排序.

定义dp[i],表示执行指令i的最早时间,则有:dp[i]=max(dp[i],dp[j]+a[j][i]),a[j][i]表示i必须在j执行后a[j][i]秒执行

#include <bits/stdc++.h>
using namespace std;
const int maxn = 10005;
stack<int> stk;
struct edge{
    int to, nx, w;
}e[maxn];
int n, m, len, ans = 1, head[maxn], rd[maxn], dp[maxn];
void insert(int x, int y, int w){//插边
    e[++len].to = y;
    e[len].nx = head[x];
    e[len].w = w;
    head[x] = len;
}
void kahn(){//kahn算法
    stack<int> stk;
    for(int i=1; i<=n; i++)
        if(!rd[i]){//入度为零,进栈
            stk.push(i);
            dp[i] = 1;
        }
    while(!stk.empty()){
        int u = stk.top();//取出栈顶入度为0的点
        stk.pop();
        for(int i=head[u]; i; i=e[i].nx){
            int v = e[i].to, w = e[i].w;
            rd[v] --;
            dp[v] = max(dp[v], dp[u] + w);//如果有多个限制条件,必须满足最远的那个
            ans = max(ans, dp[v]);
            if(!rd[v]) stk.push(v);
        }
    }
}
int main(){
    while(scanf("%d%d", &n, &m) != EOF){
        memset(head, 0, sizeof(head));
        memset(rd, 0, sizeof(rd));
        len = 0;
        for(int i=1; i<=m; i++){
            int x, y, w; scanf("%d%d%d", &x, &y, &w);
            insert(x, y, w);
            rd[y] ++;
        }
        kahn();
        printf("%d
", ans);
    }
    return 0;
}

免责声明:文章转载自《Instrction Arrangement[hdu4109][拓扑排序+dp]》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇二叉排序树Linux菜鸟入门级命令大全下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

LeetCode 207. Course Schedule(拓扑排序)

题目 题意:有n门课程,就是n个顶点,有m个对应关系:x,y,表示只有先上了y,才能上x。也就是x到y有一条有向边。问你求是否存在环。 题解:对于有向图求是否存在环,可以用拓扑排序,拓扑排序就是寻找入度为0的顶点,然后删去,并减少相邻点的入度,再寻找入度为0的点,直到所有顶点都删去,如果存在换,那么一定会有一些点是无法删除的。 class Solutio...

图论及其应用——图

我们探索某个领域的知识,无不怀揣的核弹级的好奇心与求知欲,那么,今天,我们就将开始对图论的探索。观察一副《机械迷城》的一处谜题。 不得不承认,《机械迷城》这款解密游戏难度远胜于《纪念碑谷》,其中一个困难点就在于——《纪念碑谷》的目标是很明确的,但是《机械迷城》往往需要自己凭感觉设立目标。而这里的关卡的目标,就是堵住第三个出水口。为了解决这个谜题,如果不去考...