拓扑排序
P1113 杂务
输入格式
第1行:一个整数 \(n\ (3 \le n \le 10{,}000)\),必须完成的杂务的数目;
第 \(2\) 至 \(n+1\) 行,每行有一些用空格隔开的整数,分别表示:
- 工作序号(保证在输入文件中是从 \(1\) 到 \(n\) 有序递增的);
- 完成工作所需要的时间 \(len\ (1 \le len \le 100)\);
- 一些必须完成的准备工作,总数不超过 \(100\) 个,由一个数字 \(0\) 结束。有些杂务没有需要准备的工作只描述一个单独的 \(0\)。
保证整个输入文件中不会出现多余的空格。
输出格式
一个整数,表示完成所有杂务所需的最短时间。
输入输出样例 #1
输入 #1
7
1 5 0
2 2 1 0
3 3 2 0
4 6 1 0
5 1 2 4 0
6 8 2 4 0
7 4 3 5 6 0
输出 #1
23
由于要先做某事,才能接着完成另一件事,所以采用拓扑排序。我们对输入进行编码:
for(int i=1;i<=n;i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
t[i]=b;
while(c)
{
degree[a]++; //e[c]表示以c为前驱的节点
e[c].push_back(a); //这样凡是前面多一个前驱的节点,入度都要+1
scanf("%d",&c);
}
}
再进行bfs:
void bfs()
{
queue<int> q;
for(int i=1;i<=n;i++)
{
f[i]=t[i];
if(degree[i]==0) //先将入度为0的节点直接入队
q.push(i);
}
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=0;i<e[u].size();i++)
{
int v=e[u][i];
degree[v]--; //由于u已经离队,所以节点v的入度就减少
f[v]=max(f[v],t[v]+f[u]);
if(!degree[v])
q.push(v);
}
}
}

浙公网安备 33010602011771号