7-3 最短工期

题目概述:

求有依赖关系的工程的最早完工时间。如果不可能,则输出impossible。

思路:

一开始想的是dijkstra求最长路,但是不对,因为dijkstra是单源点,而此题可以有多个源点和汇点。

判是否可行:若不存在源点或汇点则不可行,即至少要有一个入度为0的点和一个出度为0的点。

求最早完成时间

拓扑排序+关键路径。

利用队列实现,不断将未标记的入度为0的点入队,并将与其相邻的点的入度减去。

if(--in[i]==0) q[++tt] = i;

若未搜过且存在路径,则可更新。

if(!st[i] && g[t][i] >= 0) 
		dist[i] = max(dist[i], dist[t]+g[t][i]);

更新路径的同时,判断存最长路,这样就可以不用遍历找最长汇点了。

ans = max(ans, dist[i]);

 注意路径初始化为负无穷。

//要有一个入度为0的起始点和出度为0的结束点
#include<iostream>
#include<cstring>
#include<vector>
using namespace std;

const int N = 105;
int g[N][N], in[N], out[N];
int n, m, s, e;
int dist[N], q[N*5];
bool st[N];


int main() {

	memset(g, -0x3f, sizeof g);

	cin >> n >> m;
	while(m--) {
		int a, b, c;
		cin >> a >> b >> c;
		g[a][b] = max(g[a][b], c);
		in[b] ++, out[a] ++;
	}

	s = e = -1;
	int hh = 0, tt = -1;
	for(int i = 0; i < n; ++ i) {
		if(in[i] == 0) {
			s = i;
			q[++ tt] = i;
			dist[i] = 0;
		}
		if(out[i] == 0) e = i;
	}
	//cout << s << e << endl;
	if(s == -1 || e == -1) {
		puts("Impossible");
		return 0;
	}

	int ans = 0;
	while(hh <= tt) {
		int t = q[hh ++];
		st[t] = true;

		for(int i = 0; i < n; ++ i) {
			if(!st[i] && g[t][i] >= 0) {
				dist[i] = max(dist[i], dist[t]+g[t][i]);
				//printf("t=%d i=%d dist[i]=%d\n",t,i,dist[i]);
				ans = max(ans, dist[i]);
				if(--in[i]==0) q[++tt] = i;
			}//cout << in[4] << endl;
		}
	}

	cout << ans << endl;
	return 0;
}

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值