您的位置:首页 > 其它

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]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: