P1260 【工程规划】
题目非常得简洁明了,差分约束的裸题,甚至连不等式都给你写出来了
没什么好分析的,直接看不等式建立方程(这里把\(Ti\)和\(Tj\)都表示为\(i\)和\(j\))
因为求的应该是最早的开始时间,我们应该转化为\(≥\),然后跑最长路求解
\(i-j \leq b\)
\(-j \leq b-i\)
\(j \geq i-b\)
那么就应该是从\(i\)到\(j\)建一条负边权
至于为什么是跑最长路,如果不太理解的话可以看看我的博客
其实我们可以用数学的方法简单地思考一下这个问题
\(\begin{cases}x\leq10\\x\leq5\\\end{cases}\) 和 \(\begin{cases}y\geq10\\y\geq5\\\end{cases}\)
我们得出的答案应该是 \(x \leq 5\) 和 \(y \geq10\) (初中数学基本知识),我们应该的正解应该是范围更小的那一个。对于小于等于,最短路会使得答案范围更小;相反,大于等于的话,最长路使得答案范围更小,满足不等式组的求解
那么对于无解的情况,就是通过SPFA判负环就可以了,如果不会的话建议先做这一道题,顺便推荐一下同桌的博客
那么应该就没什么疑问了,直接看代码
#include<bits/stdc++.h>
using namespace std;
const int MAXN=5*1e6+51;
int n,m;
struct node{
int net,to,w;
}e[MAXN];
int head[MAXN],tot;
void add(int x,int y,int z){
e[++tot].net=head[x];
e[tot].to=y;
e[tot].w=z;
head[x]=tot;
}
int d[MAXN],vis[MAXN];
bool v[MAXN];
queue<int>q;
bool spfa(int s){
for(register int i=0;i<=n;i++) d[i]=-20040915;
d[s]=0,v[s]=true,vis[s]=1;
q.push(s);
while(!q.empty()){
int x=q.front();
q.pop();
v[x]=false;
for(register int i=head[x];i;i=e[i].net){
int y=e[i].to,z=e[i].w;
if(d[y]<d[x]+z){
d[y]=d[x]+z;
if(v[y]==false){
v[y]=true;
vis[y]++;
if(vis[y]>=n) return false;
q.push(y);
}
}
}
}
return true;
}
int main(){
scanf("%d%d",&n,&m);
for(register int i=1;i<=m;i++){
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add(y,x,z);
}
for(register int i=1;i<=n;i++) add(0,i,0);
if(spfa(0)==false) puts("NO SOLUTION");
else{
for(register int i=1;i<=n;i++) printf("%d\n",d[i]);
}
return 0;
}
如果有错的地方请指出啊,希望对大家有帮助