差分约束
差分约束模板
经验
差分约束求值:最大值(最短路),最小值(最长路)
差分约束判断:最长路和最短路都可以。
最长路转化形式:$x_u - x_v >= y$
最短路转化形式:$x_u - x_v <= y$
#include<iostream>
#include<cstring>
#include<queue>
#define maxn 50007
using namespace std;
struct edge {
int to, val, nxt;
}g[maxn];
int n, m, cnt, dis[maxn], hd[maxn], sum[maxn];
bool vis[maxn]; queue<int> q;
void add(int u, int v, int w)
{
g[++cnt].val = w;
g[cnt].to = v;
g[cnt].nxt = hd[u];
hd[u] = cnt;
}
bool spfa()
{
memset(dis, 80, sizeof(dis));
memset(vis, 0, sizeof(vis));
dis[0] = 0, vis[0] = true;
q.push(0), ++sum[0];
while (!q.empty())
{
int u = q.front();
q.pop();
vis[u] = false;
for (int i = hd[u]; i; i = g[i].nxt)
{
int v = g[i].to;
if (dis[v] > dis[u] + g[i].val)//dis[v] > dis[u] + g[i].val 最短路,最长路
{
dis[v] = dis[u] + g[i].val;
if (!vis[v])
{
vis[v] = true;
q.push(v);
if (++sum[v] >= n + 1)
return false;
}
}
}
}
return true;
}
int main(void)
{
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> n >> m;
for (int i = 1, u, v, w; i <= m; i++)
{
cin >> u >> v >> w;
add(v, u, w);
}
for (int i = 1; i <= n; i++)
add(0, i, 0);
if (spfa())
for (int i = 1; i <= n; i++)
cout << dis[i] << ' ';
else
cout << "NO" << '\n';
return 0;
}

浙公网安备 33010602011771号