poj 3159 差分约束

听着名字挺高大上的,其实就是形如下列不等式的集合   C-A <= k   ,那么为什么取这个名字:“差分”:因为左边是两个变量的差,“约束”:这个式子有 <= k 这个限制条件。

然后着眼解决方案,通过观察可以得到,它和最短路的松弛操作很像:当 dis[v] > dis[u] + w[u,v] 时松弛,即算法正常执行结束后,dis[v] - dis[u]<= w[u,v] 恒成立,于是就可以转换成求最短路的问题。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;

const int inf = 0x3f3f3f3f;
const int N = 30100;
const int M = 160000;

int tot;
struct Edge{
	int v, cost, next; 
}edge[M];
struct qnode{
	int v, c;
	bool operator < (const qnode &x) const {
		return c > x. c;
	}
};
int head[M];
bool vis[N];
int dis[N];

void addedge(int u, int v, int w){
	edge[tot]. v = v;
	edge[tot]. cost = w;
	edge[tot]. next = head[u];
	head[u] = tot ++;
}

void dijkstra(){
	memset(vis, false, sizeof(vis));
	memset(dis, 0x3f, sizeof(dis));
	dis[1] = 0;
	priority_queue <qnode> q;
	q. push({1, 0});
	while(! q. empty()){
		qnode t = q. top();
		q. pop();
		if(vis[t. v])
			continue;
		vis[t. v] = true;
		for(int i = head[t. v]; i != -1; i = edge[i]. next){
			int v = edge[i]. v;
			int cost = edge[i]. cost;
			if(! vis[v] && dis[v] > dis[t. v] + cost){
				dis[v] = dis[t. v] + cost;
				q. push({v, dis[v]});
			}
		}
	}
}

int main(){
	int n, m;
	while(~ scanf("%d%d", &n, &m)){
		int a, b, c;
		tot = 1;
		memset(head, -1, sizeof(head));
		while(m --){
			scanf("%d%d%d", &a, &b, &c);
			addedge(a, b, c);
		}
		dijkstra();
		printf("%d\n", dis[n]);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_38759433/article/details/80161733