题目描述
给定有向图无环的边信息,求每个顶点的最早开始时间、最迟开始时间。
输入
第一行图的顶点总数
第二行边的总数
第三行开始,每条边的时间长度,格式为源结点 目的结点 长度
输出
第一行:第个顶点的最早开始时间
第二行:每个顶点的最迟开始时间
输入输出样例
输入样例1 <-复制
9
12
0 1 3
0 2 10
1 3 9
1 4 13
2 4 12
2 5 7
3 6 8
3 7 4
4 7 6
5 7 11
6 8 2
7 8 5
输出样例1
0 3 10 12 22 17 20 28 33
0 9 10 23 22 17 31 28 33
AC代码
#include<iostream>
using namespace std;
int n, m; // 表示矩阵的行数和列数
int juzhen[100][100]; // 存储输入的矩阵
int fuzhi[100][100]; // 存储矩阵的副本,用于拓扑排序
int visit[100]; // 记录列的访问情况
struct dian
{
int xu; // 列的序号
int ve, vl; // ve和vl的值
};
dian d[100]; // 存储每列的信息
int xun()
{
int i, j;
for (j = 0; j < n; j++)
{
int flag = 0;
for (i = 0; i < n; i++)
{
if (fuzhi[i][j] != 0)
flag = 1;
}
if (flag == 0 && visit[j] == 0) // 找到全为0且未被选过的列
{
visit[j] = 1; // 标记为已访问
return j; // 返回列的序号
}
}
}
int cha(int biao)
{
int i;
for (i = 0; i < n; i++)
if (d[i].xu == biao)
return i; // 根据列的序号找到在d数组中的位置
}
int main()
{
cin >> n >> m; // 输入矩阵的行数和列数
int i, j, k;
for (k = 0; k < m; k++)
{
cin >> i >> j;
cin >> juzhen[i][j]; // 输入矩阵的元素
}
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
fuzhi[i][j] = juzhen[i][j]; // 复制矩阵到副本
int t = 0;
for (k = 0; k < n; k++) // 进行拓扑排序
{
int pos = xun(); // 找到满足条件的列
d[t++].xu = pos; // 存储列的序号
for (j = 0; j < n; j++)
fuzhi[pos][j] = 0; // 将该列对应的矩阵元素置为0
}
d[0].ve = 0; // 设置ve的初始值为0
for (i = 1; i < n; i++) // 求ve
{
int hao = d[i].xu; // 获取列的序号
int max = 0;
for (k = 0; k < n; k++)
{
if (juzhen[k][hao] != 0)
{
int zhi = d[cha(k)].ve + juzhen[k][hao]; // 计算ve的值
if (zhi > max)
max = zhi;
}
}
d[i].ve = max; // 存储ve的值
}
d[n - 1].vl = d[n - 1].ve; // 设置vl的初始值为ve的值
for (i = n - 2; i >= 0; i--) // 求vl
{
int hao = d[i].xu; // 获取列的序号
int min = 1000;
for (k = 0; k < n; k++)
{
if (juzhen[hao][k] != 0)
{
int zhi = d[cha(k)].vl - juzhen[hao][k]; // 计算vl的值
if (zhi < min)
min = zhi;
}
}
d[i].vl = min; // 存储vl的值
}
for (i = 0; i < n; i++)
{
int pos = cha(i); // 获取列在d数组中的位置
cout << d[pos].ve << " "; // 输出ve的值
}
cout << endl;
for (i = 0; i < n; i++)
{
int pos = cha(i); // 获取列在d数组中的位置
cout << d[pos].vl << " "; // 输出vl的值
}
cout << endl;
}
该代码实现了拓扑排序和关键路径的计算。首先,根据输入的矩阵,构建副本并进行拓扑排序,得到列的顺序。然后,计算每列的ve值和vl值。最后,输出ve和vl的结果。
通过拓扑排序,找到全为0且未被选过的列,将其加入d数组中。然后,根据拓扑排序的顺序,依次计算ve和vl的值。
代码中使用了一个结构体dian
来存储每列的信息,包括列的序号、ve值和vl值。使用数组d
来存储这些结构体,通过cha
函数根据列的序号查找对应的结构体位置。
在主函数中,首先读取输入的矩阵的行数和列数,然后根据输入的矩阵构建副本,并进行拓扑排序得到列的顺序。接着,计算每列的ve值和vl值,并输出结果。
(by 归忆)