http://acm.hdu.edu.cn/showproblem.php?pid=4109
题意:给你一些机器指令,某些有先后顺序(若A->B,C->B则必须A、C执行完才能执行B),且有安全距离(若A->B 距离n)那么必须在从A执行算起n时间,才能执行B,一次可以运行多个指令,指令的完成只花费1,最后求执行完所有指令所需的最短的时间。
先拓扑排序,然后对拓扑序中的每个点tp[i],其完成指令时间为t[tp[i]]=max{t[tp[j]]+a[j][tp[i]],0<=j<i,j和tp[i]之间有路径时}
所有点时间的最大值即为结果。
入度为0的那一批点为最早运行指令的点,运行时间为1,故t数组初始为1。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;
int a[1010][1010];
int main()
{
int i,j,k,n,m,p[1010],d,tp[1010],t[1010],time;
while (1)
{
if (scanf("%d%d",&n,&m)==EOF) break;
for (i=0;i<=n;i++)
for (j=0;j<=n;j++) a[i][j]=-1;
for (i=0;i<=n;i++) p[i]=0;
for (i=0;i<=n;i++) t[i]=1;
for (i=1;i<=m;i++)
{
scanf("%d%d%d",&j,&k,&d);
p[k]++;
a[j][k]=d;
}
int num=0;
for (i=1;i<=n;i++)
{
for (j=0;p[j]!=0;j++);
num++;
tp[num]=j;
p[j]=-1;//作为以完成拓扑点的标记,这种点入度也是0
for (k=0;k<=n-1;k++)
if (a[j][k]!=-1) p[k]--;
}
time=0;
for (i=2;i<=n;i++)
{
for (j=0;j<i;j++)
if (a[j][tp[i]]!=-1)
{
int tt=t[j]+a[j][tp[i]];
if (tt>t[tp[i]]) t[tp[i]]=tt;
if (tt>time) time=tt;
}
}
printf("%d\n",time);
}
return 0;
}