1260 工程规划
萌新刚刚学会差分约束,很多大佬的解释我都不会
大家都知道,差分约束有m个不等式,要找到一组解,满足所有的约束,因为不等式都是差分形态,所以要满足所有约束,所以叫做差分约束
我们采取这样的方式建边:对于ai-aj<=b,从j向i连一条边权为b的边
SPFA判断负环已经有说明,不再说了
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
inline int read()
{
int ans = 0,op = 1;
char ch = getchar();
while(ch < '0' || ch > '9')
{
if(ch == '-') op = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9')
{
(ans *= 10) += ch - '0';
ch = getchar();
}
return ans * op;
}
const int maxn = 2005;
struct egde
{
int to,next,cost;
}e[maxn * 10];
int fir[maxn],alloc;
inline void adde(int u,int v,int w)//邻接表存储
{
e[++alloc].next = fir[u];
fir[u] = alloc;
e[alloc].to = v;
e[alloc].cost = w;
}
int n,m;
int dis[maxn],popst[maxn],minm;
bool instack[maxn];//标记
void spfa(int s)
{
queue<int> q;
memset(dis,0x3f,sizeof(dis));
dis[s] = 0;
q.push(s);
instack[s] = 1;
while(q.size())
{
int u = q.front();
q.pop();
popst[u]++;
if(popst[u] > n - 1) { printf("NO SOLUTION"); return;}//路径答案超出限制
instack[u] = 0;
for(int i = fir[u];i;i = e[i].next)
{
int v = e[i].to,w = e[i].cost;
if(dis[v] > dis[u] + w)//进行松弛
{
dis[v] = dis[u] + w;
if(!instack[v]) q.push(v),instack[v] = 1;//计算答案
}
}
}
for(int i = 1;i <= n;i++) minm = min(minm,dis[i]);
for(int i = 1;i <= n;i++) printf("%d\n",dis[i] - minm);//总长度减去最短的长度类似于 1250
}
int main()
{
n = read(),m = read();
for(int i = 1;i <= m;i++)
{
int u = read(),v = read(),w = read();
adde(v,u,w);
}
for(int i = 1;i <= n;i++) adde(n + 1,i,0);//差分边
spfa(n + 1);//跑最短路
return 0;
}