AcWing 1170. 排队布局 题解(spfa求负环解决约束差分)

AcWing 1170. 排队布局
这里要注意求的是最大值,所以要用最短路,建图的时候也是从大于号指向小于号
大佬题解

#include

using namespace std;

const int N = 1010, M = 3e4 + 10, INF = 0x3f3f3f3f;

int n, m;
int h[N], e[M], ne[M], w[M], idx;
int dist[N];
bool st[N];
int cnt[N];
int q[N];

void add(int a, int b, int c){
	e[idx] = b;
	w[idx] = c;
	ne[idx] = h[a];
	h[a] = idx ++ ;
}

int spfa(int size){  //将1~size的点入队

	int hh = 0, tt = 0;
	memset(dist, 0x3f, sizeof dist);
	memset(cnt, 0, sizeof cnt);
	memset(st, 0, sizeof st);
	
	for(int i = 1; i <= size; i ++ ){
		q[tt ++ ] = i;
		dist[i] = 0;  //初始化初始点距离为0 
		st[i] = true;
	}
	
	while(hh != tt){
		int t = q[hh ++ ];
		if(hh == N) hh = 0;
		st[t] = false;
		
		for(int i = h[t]; ~i; i = ne[i]){
			int j = e[i];
			if(dist[j] > dist[t] + w[i]){
				dist[j] = dist[t] + w[i];
				cnt[j] = cnt[t] + 1;
				if(cnt[t] >= n) return true;
				if(!st[j]){
					q[tt ++ ] = j;
					if(tt == N) tt = 0;
					st[j] = true;
				}
			}
		}
	}
	return false;
}

int m1, m2;

int main()
{
	cin>>n>>m1>>m2;
	memset(h, -1, sizeof h); 
	for(int i = 1; i < n; i ++ ) add(i + 1, i, 0);  //x[i] ≤ x[i+1]+0 因为这里是求最短路径,所以要由大于号推出小于号 
	while(m1 -- ){
		int a, b, c;
		cin>>a>>b>>c;
		if(a > b) swap(a, b);  
		add(a, b, c);  //x[b] ≤ x[a] + L a→b
	}
	while(m2 -- ){
		int a, b, c;
		cin>>a>>b>>c;
		if(a > b) swap(a, b);
		add(b, a, -c);  //x[a] ≤ x[b]-D  b→a
	}
	
	if(spfa(n)) puts("-1");
	else{
		spfa(1);
		if(dist[n] == INF) puts("-2");
		else cout<<dist[n]<<endl;
	} 
	return 0;
}

你可能感兴趣的:(#,负环,图论,图论,算法)