算法训练-拓扑排序2

洛谷P1807最长路 https://www.luogu.com.cn/problem/P1807

本题数据范围过大盲目使用dfs容易超时爆栈

题目要求中提到i < j所以节点1的入度肯定为0

求1~n的最长路径所以能想到继续使用拓扑排序,但是有的点既能被1到达还能被其他入度为0的点到达,会影响后面的结果,前几次提交的时候只有55pts就是因为没有考虑到别的入度为0的点对答案的影响

所以应该继续按照拓扑排序的思路先把其他入度为0的点及其相关边删掉

最后再进行一遍先把1入队的拓扑排序就行了

tips:还要判断能不能到达

#include 
#define int long long
#define endl '\n'
/*
	===\\================//\\===================//\\============//\\==========//=====
	====\\==============//==\\=================//==\\==========//==\\========//=
	=====\\============//====\\===============//====\\========//====\\======//====
	======\\==========//======\\=============//======\\======//======\\====//===
	=======\\========//========\\===========//========\\====//========\\==//====
	========\\======//==========\\=========//==========\\==//===========||========
	=========\\====//============\\=======//=============||===========//==\\====
	==========\\==//==============\\=====//==============||==========//====\\====
	===========\\//================\\===//===============||=========//======\\====
	============\/==================\\=//================||========//========\\=
	============..===================\=/=================||=======//==========\\=====
	================ /            |               \
	================/  .   ```\   |                \
	================|      ___|   |         /      |
	================\  .   .../   |        /       /
	_(:з」∠)_	____ \         ___|       /______ / ______
*/
using namespace std;
typedef long long ll;
const int N = 1e5 + 10, base = 26, inf = 1e18, mod = 80112002, MOD = 998244353, INF = (1LL << 60) - 1;

int n, m;
int out[1510], in[1510], f[1510];
vector> e[1510];

void wyx() {
	cin >> n >> m;
	for (int i = 0; i < m; i ++ ) {
		int u, v, w;
		cin >> u >> v >> w;
		e[u].push_back({v, w});
		out[u] ++ ;
		in[v] ++ ;
	}
	queue q;
	for (int i = 2; i <= n; i ++ ) {
		f[i] = -1e9;
		if (!in[i]) q.push(i);
	}
	while (!q.empty()) {
		int x = q.front();
		q.pop();
		for (auto entry : e[x]) {
			in[entry.first] -- ;
			if (in[entry.first] == 0) q.push(entry.first);
		}
	}
	q.push(1);
	while (!q.empty()) {
		int u = q.front();
		q.pop();
		for (auto entry : e[u]) {
			int v = entry.first;
			int w = entry.second;
			if (f[v] < f[u] + w) f[v] = f[u] + w;
			in[v] -- ;
			if (in[v] == 0) q.push(v);
		}
	}
	if (f[n] == -1e9) cout << -1 << endl;
	else cout << f[n] << endl;
}

signed main() {
	ios::sync_with_stdio(false); cin.tie(0);
	int t = 1; //cin >> t; 
	while (t--) {wyx();} return 0;
}

你可能感兴趣的:(算法,深度优先)