hdu 4109 拓扑排序 关键路径
2015-08-11 11:15
393 查看
Instrction Arrangement
[b]Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1266 Accepted Submission(s): 524
[/b]
Problem Description
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.解析:解决这个问题是要求出某个活动所用的最长时间,因为一个活动可能必须在另一个活动完成之后w时间内才能完成,所以整个工程的完成是在某个点完成之后才能完成,只要求出这个点所用的时间就是整个工程所用的时间由此题来学习关键路径:AOE网 在现代化管理中,人们常用有向图来描述和分析一项工程的计划和实施过程,一个工程常被分为多个小的子工程,这些子工程被称为活动(Activity),在带权有向图中若以顶点表示事件,有向边表示活动,边上的权值表示该活动持续的时间,这样的图简称为AOE网,如下图。 AOE网具有以下性质: (1)只有在某顶点所代表的事件发生后,从该顶点出发的各有向边所代表的活动才能开始。 (2)只有在进入某点的各有向边所代表的活动都已结束,该顶点所代表的时事件才能发生。 可以将上图假想一个工程有6项活动,网中5个顶点,分别表示5个事件,边上的权值分别表示各项活动所需要的时间,事件v1表示工程开始,事件v3表示活动3和4完成后,活动5可以开始,事件v4表示活动2完成活动4和活动6开始,v5表示活动1完成活动3开始,事件v2表示工程结束。 关键路径及其算法 1.关键路径:在AOE网中所关心的问题是完成整个工程至少需要多少时间和哪些活动是影响整个工程进度的关键。由于AOE网中的某些活动能够平行地进行,故完成整个工程所需的时间是从开始顶点到结束顶点的最长路径长度(路径上的权值和)最长路径叫关键路径。如上述工程的关键路径是1->4->3->2,关键路径长度为2+7+6=15,关键活动是a2,a4,a5。代码模板:时间很长M:1952 T:1252[code]#include<iostream> #include<string.h> #include<algorithm> #include<queue> using namespace std; const int N = 1010; const int M = 10010; int n, m, head , degree ; struct p { int to, from, next, w; }edge[M]; void topo() { queue<int>q; int temp ; int time ; memset(time, 0, sizeof(time)); int count0=0,flag=0; for(int i=0;i<n;i+=count0){ count0=0; for(int j=0;j<n;j++) if(degree[j]==0){ temp[count0++]=j; degree[j]--; if(flag==0)time[j]=1; } flag++; for(int j=0;j<count0;j++){ int u=temp[j]; for(int k=head[u];k!=-1;k=edge[k].next){ int v = edge[k].to; int w = edge[k].w; time[v] = max(time[v], time[u] + w); degree[v]--; } } } /*for (int i = 0; i < n;i++) if (degree[i] == 0){ q.push(i); time[i] = 1; } while (!q.empty()){ int u = q.front(); q.pop(); for (int k = head[u]; k != -1; k = edge[k].next){ int v = edge[k].to; int w = edge[k].w; time[v] = max(time[v], time[u] + w); degree[v]--; if (!degree[v])q.push(v); } } */ int maxn = 0; for (int i = 0; i < n; i++) maxn = max(time[i], maxn); cout << maxn << endl; } int main() { while (cin >> n >> m){ memset(head, -1, sizeof(head)); memset(degree, 0, sizeof(degree)); int u, v, w; for (int i = 0; i < m; i++){ cin >> u >> v >> w; edge[i].from = u; edge[i].to = v; edge[i].w = w; edge[i].next = head[u]; head[u] = i; degree[v]++; } topo(); } }
一下使用队列来存储入度为0的点:M:1856 T:826#include<iostream>
#include<string.h>
#include<string>
#include<algorithm>
#include<queue>
using namespace std;
#define N 1010
#define M 10010
int n,m,head
,degree
;
struct p
{
int to,from,next,w;
}edge[M];
void topo()
{
queue<int>q;
int time
;
memset(time,0,sizeof(time));
for(int i=0;i<n;i++)
if(degree[i]==0){
q.push(i);
time[i]=1;
}
while(!q.empty()){
int u=q.front();q.pop();
for(int k=head[u];k!=-1;k=edge[k].next){
int v=edge[k].to;
int w=edge[k].w;
time[v]=max(time[v],time[u]+w);
degree[v]--;
if(!degree[v])q.push(v);
}
}
int maxn=0;
for(int i=0;i<n;i++){
maxn=max(time[i],maxn);
}
cout<<maxn<<endl;
}
int main()
{
while(cin>>n>>m){
memset(head,-1,sizeof(head));
memset(degree,0,sizeof(degree));
int u,v,w;
for(int i=0;i<m;i++){
cin>>u>>v>>w;
edge[i].from=u;
edge[i].to=v;
edge[i].next=head[u];
head[u]=i;
degree[v]++;
edge[i].w=w;
}
topo();
}
return 0;
}
[/code]
相关文章推荐
- Ubuntu安装ssh,及失败解决方案
- fiddler stave插件
- Belkasoft Evidence Center could handle Chinese characters well
- python setup.py install 失败
- 解决有些Eclipse无法启动安装的Tomcat而是Eclipse自带的Tomcat
- 回车符,换行符与'\0'
- MySQL必知必会笔记(三)SELECT语句 联结表 高级联结 组合查询 全文本搜索
- ACdream 1073 雷霆战机
- android学习笔记NO.2
- Controller正反向传值
- php辗转法实现最大公约数
- iOS最简单方法判断网络类型——通过状态栏显示
- 100分程序员的8个习惯
- ios中assign、copy 、retain、strong、weak的区别
- Flexbox参数详解
- [LeetCode] Implement Stack using Queues
- Java语言基础组成(一)
- Linux电源管理(2)_Generic PM之基本概念和软件架构
- UDP传输协议的基本应用-发送和接收
- 修改ssh和ssl版本号