差分约束?差分约束!

zhuliqin 2023-10-29 10:55:05 2023-10-29 10:59:15 11 返回题目

一眼定真,把约束转移到前缀和数组上。那么我们对于任意 之间要种 棵树的限制,转化为 。同时添加 的限制,跑差分约束即可。最劣复杂度

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n, m;
int dis[30005], vis[30005], inq[30005];
vector<int >vc[30005], w[30005];
void spfa() {
	queue<int > q;
	q.push(1);
	dis[1] = 0;
	vis[1] = 1;
	while(!q.empty()) {
		int p = q.front();
		int v = dis[p];
		q.pop();
		inq[p] = 0;
		for(int i = 0;i < vc[p].size();i ++)
			if(v + w[p][i] < dis[vc[p][i]]) {
				if(++vis[vc[p][i]] > n + 1) {
					cout << "No";
					exit(0);
				}
				if(!inq[vc[p][i]])
					q.push(vc[p][i]), dis[vc[p][i]] = v + w[p][i], inq[vc[p][i]] = 1;
				else 
					dis[vc[p][i]] = v + w[p][i];
			}
	}
}
signed main() {
	memset(dis, 0x3f, sizeof dis);
	cin >> n >> m;
	for(int i = 1;i <= m;i ++) {
		int t, u, v;
		cin >> u >> v >> t;
		u += 1;
		v += 2;
		vc[v].push_back(u);
		w[v].push_back(-t);
	}
	for(int i = 3;i <= n + 2;i ++) {
		vc[i - 1].push_back(i);
		w[i - 1].push_back(1);
		vc[i].push_back(i - 1);
		w[i].push_back(0);
	}
	
	for(int i = 2;i <= n + 2;i ++) {
		vc[1].push_back(i);
		w[1].push_back(0);
	}
	spfa();
	cout << dis[n + 2] - dis[2]; 
	return 0;
}
{{ vote && vote.total.up }}