题目描述

Ali has taken the Computer Organization and Architecture course this term. He learned that there may be dependence between instructions, like WAR (write after read), WAW, RAW.

If the distance between two instructions is less than the Safe Distance, it will result in hazard, which may cause wrong result. So we need to design special circuit to eliminate hazard. However the most simple way to solve this problem is to add bubbles (useless operation), which means wasting time to ensure that the distance between two instructions is not smaller than the Safe Distance.

The definition of the distance between two instructions is the difference between their beginning times.

Now we have many instructions, and we know the dependent relations and Safe Distances between instructions. We also have a very strong CPU with infinite number of cores, so you can run as many instructions as you want simultaneity, and the CPU is so fast that it just cost 1ns to finish any instruction.

Your job is to rearrange the instructions so that the CPU can finish all the instructions using minimum time.

Input

The input consists several testcases.

The first line has two integers N, M (N <= 1000, M <= 10000), means that there are N instructions and M dependent relations.

The following M lines, each contains three integers X, Y , Z, means the Safe Distance between X and Y is Z, and Y should run after X. The instructions are numbered from 0 to N - 1.

Output

Print one integer, the minimum time the CPU needs to run.

样例

Sample Input

5 2

1 2 1

3 4 1

Sample Output

2

Hint

In the 1st ns, instruction 0, 1 and 3 are executed;

In the 2nd ns, instruction 2 and 4 are executed.

So the answer should be 2.

分析

这道题至少有两种方法

拓扑排序

第一种方法就是拓扑排序

显然没有任何约束的指令可以在第一秒同时执行。

对有一个或多个约束指令我们要满足最远的那个约束之后

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

临界没有任何约束的指令在第一秒时执行,dp[]=1

阶段很明显,当前入度为0点,下个阶段为这些点的临界点。

代码

#include <bits/stdc++.h>
const int maxn=1000+5,maxm=1e4+5;
struct Node{int to;int dis;int next;}e[maxm];
int n,m,len,head[maxn],rd[maxn],dp[maxn];
void Insert(int x,int y,int z){
e[++len].to=y;e[len].dis=z;e[len].next=head[x];head[x]=len;
}
void Kahn(){
std::stack<int> q;
for(int i=0;i<n;++i){
if(!rd[i])q.push(i),dp[i]=1;
else dp[i]=0;
}
int ans=1;
while(!q.empty()){
int u=q.top();q.pop();
for(int i=head[u];i;i=e[i].next){
int v=e[i].to,w=e[i].dis;rd[v]--;
dp[v]=std::max(dp[v],dp[u]+w);
ans=std::max(ans,dp[v]);
if(!rd[v])q.push(v);
}
}
printf("%d\n",ans);
}
void Solve(){
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,z;scanf("%d%d%d",&x,&y,&z);
Insert(x,y,z);rd[y]++;
}
Kahn();
}
}
int main(){
Solve();
return 0;
}

最长路

其实细细思考一下,建一个超级源点跑最长路也是可以的

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cmath>
using namespace std;
const int maxd=1005,maxb=20005;
int ru[maxd],chu[maxd];
int head[maxd],tot=1;
int n,m;
struct asd{
int from,to,next,val;
}b[maxb];
void ad(int aa,int bb,int cc){
b[tot].from=aa;
b[tot].to=bb;
b[tot].next=head[aa];
b[tot].val=cc;
head[aa]=tot++;
}
bool vis[maxd];
int dis[maxd];
void SPFA(){
queue<int> q;
q.push(n);
for(int i=0;i<maxd;i++){
dis[i]=-0x3f3f3f3f;
}
dis[n]=0;
while(!q.empty()){
int xx=q.front();
q.pop();
vis[xx]=0;
for(int i=head[xx];i!=-1;i=b[i].next){
int u=b[i].to;
if(dis[u]<dis[xx]+b[i].val){
dis[u]=dis[xx]+b[i].val;
if(!vis[u])q.push(u),vis[u]=1;
}
}
}
}
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
memset(head,-1,sizeof(head));
memset(vis,0,sizeof(vis));
memset(dis,0x3f,sizeof(dis));
memset(&b,0,sizeof(struct asd));
memset(ru,0,sizeof(ru));
memset(chu,0,sizeof(chu));
tot=1;
for(int i=1;i<=m;i++){
int aa,bb,cc;
scanf("%d%d%d",&aa,&bb,&cc);
ad(aa,bb,cc);
ru[bb]++;
chu[aa]++;
}
for(int i=0;i<n;i++){
if(ru[i]==0){
ad(n,i,1);
}
}
SPFA();
int ans=1;
for(int i=0;i<n;i++){
ans=max(ans,dis[i]);
}
printf("%d\n",ans);
}
return 0;
}

Instrction Arrangement UDH 4109 拓扑排序 or 最长路的更多相关文章

  1. 2017 ACM-ICPC(乌鲁木齐赛区)网络赛 H.Skiing 拓扑排序+最长路

    H.Skiing In this winter holiday, Bob has a plan for skiing at the mountain resort. This ski resort h ...

  2. [模板]tarjan缩点+拓扑排序

    题目:给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 允许多次经过一条边或者一个点,但是,重复经过的点,权值只计算一次. 题目简述:先t ...

  3. BZOJ 1194 [HNOI2006]潘多拉的盒子 (图论+拓扑排序+tarjan)

    题面:洛谷传送门 BZOJ传送门 标签里三个算法全都是提高组的,然而..这是一道神题 我们把这道题分为两个部分解决 1.找出所有咒语机两两之间的包含关系 2.求出咒语机的最长上升序列 我们假设咒语机$ ...

  4. 2018.11.06 bzoj1093: [ZJOI2007]最大半连通子图(缩点+拓扑排序)

    传送门 先将原图缩点,缩掉之后的点权就是连通块大小. 然后用拓扑排序统计最长链数就行了. 自己yyyyyy了一下一个好一点的统计方法. 把所有缩了之后的点都连向一个虚点. 然后再跑拓扑,这样最后虚点的 ...

  5. BZOJ1880:[SDOI2009]Elaxia的路线(最短路,拓扑排序)

    Description 最近,Elaxia和w**的关系特别好,他们很想整天在一起,但是大学的学习太紧张了,他们 必须合理地安排两个人在一起的时间.Elaxia和w**每天都要奔波于宿舍和实验室之间, ...

  6. 【CSP模拟赛】益智游戏(最短路(DJSPFA)&拓扑排序)

    题目描述 小P和小R在玩一款益智游戏.游戏在一个正权有向图上进行. 小P 控制的角色要从A 点走最短路到B 点,小R 控制的角色要从C 点走最短路到D 点. 一个玩家每回合可以有两种选择,移动到一个相 ...

  7. HDU 4109 Instrction Arrangement

    题目链接:https://vjudge.net/problem/HDU-4109 题目大意 有 N 个指令,标号从 0 ~ N - 1,和 M 个指令间的先后关系,每个关系都有一个权值 w,表示后一个 ...

  8. 算法与数据结构(七) AOV网的拓扑排序

    今天博客的内容依然与图有关,今天博客的主题是关于拓扑排序的.拓扑排序是基于AOV网的,关于AOV网的概念,我想引用下方这句话来介绍: AOV网:在现代化管理中,人们常用有向图来描述和分析一项工程的计划 ...

  9. 有向无环图的应用—AOV网 和 拓扑排序

    有向无环图:无环的有向图,简称 DAG (Directed Acycline Graph) 图. 一个有向图的生成树是一个有向树,一个非连通有向图的若干强连通分量生成若干有向树,这些有向数形成生成森林 ...

随机推荐

  1. STL关联容器

    这里简单学习一下STL关联容器,主要是map.multimap.set.multiset以及unordered_map.前四个底层实现都是利用红黑树实现的,查找算法时间复杂度为\(O(log(n))\ ...

  2. iOS -程序启动原理和UIApplication的介绍

    一.UIApplication 简介       (1)UIApplication对象是应用程序的象征,一个UIApplication对象就代表一个应用程序. (2)每一个Application都有自 ...

  3. TensorFlow从0到1之矩阵基本操作及其实现(7)

    矩阵运算,例如执行乘法.加法和减法,是任何神经网络中信号传播的重要操作.通常在计算中需要随机矩阵.零矩阵.一矩阵或者单位矩阵. 本节将告诉你如何获得不同类型的矩阵,以及如何对它们进行不同的矩阵处理操作 ...

  4. rust 学习之旅二,关键字和保留字

    当前,以下关键字具有所描述的功能. as-执行原始类型转换,消除包含项目的特定特征的歧义,或在useand extern crate语句中重命名项目async-返回a Future而不是阻塞当前线程a ...

  5. cb35a_c++_STL_算法_for_each

    cb35a_c++_STL_算法_for_each for_each(b,e,p)使用for_each()算法遍历数据使用for_each()和函数对象修改数据使用for_each()的返回值 //转 ...

  6. WIN10下如何解决PL2303驱动不可用的问题或者com口显示黄色感叹号usb-to-serial

    WIN10下如何解决PL2303驱动不可用的问题或者com口显示黄色感叹号usb-to-serial

  7. 这样让你的 IDEA 好用到飞起来!

    IDEA提高效率的配置项,每个开发者必须掌握的技能!下面这 32 条完美设置成功后,开发效率显著提升. 1.设置maven 1.在File->settings->搜索maven 2.Mav ...

  8. MySQL的使用方法和视图、索引、以及存储过程的一些简单方法

    一,基本概念 1, 常用的两种引擎:         (1) InnoDB        a,支持ACID,简单地说就是支持事务完整性.一致性:         b,支持行锁,以及类似ORACLE的一 ...

  9. Java中在数字前自动补零方法

    /** * 数字前面自动补零 * @param number 数字 * @return */ public static String geFourNumber(int number){ Number ...

  10. Java中堆栈的区别

    简单的说: Java把内存划分成两种:一种是栈内存,一种是堆内存. 在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配. 当在一段代码块定义一个变量时,Java就在栈中为这个变量分 ...