对于差分约束其实就是求最短(长)路的过程
x1-x2<=7…1
x2-x3<=3…2
x1-x3<=9…3
求(x1-x3)max=?
要同时满足1
2
3
三个式子 => 求交集
1+2
=>(x1-x3)max=10
3
=>( x1-x3 )max=9
(x3-x1)max=9
- if(dis[v]<=dis[u]+w) dis[v]=dis[u]+w;
相当于求最长路
—> x3-x1<=9
—> x3<=x1+9
P1993
- 建 图
最 短 路:
最 长 路:
超级源点
for(register int i=1;i<=n;i++){
add(0,i,0);
}
- 判 断
图中有环时则不存在(不存在 a>b && b>c && c>a )
——>
最短路判负环
——>
最长路判正环BFS
此题卡BFS,只有60分,超时(T_T)
inline int spfa(){
queue<int> que;
memset(dis, -0x3f, sizeof(dis));
dis[0]=0;
vis[0]=1;
que.push(0);
while(!que.empty()){
int find=que.front();
cnt[find]++;
if(cnt[find]>=n){//判断条件
flag=0;
break;
}
que.pop();
vis[find]=0;
for(int i=head[find];i!=0;i=e[i].next){
int u=e[i].from;
int v=e[i].to;
int w=e[i].weight;
if(dis[u]+w>dis[v]){
dis[v]=dis[find]+w;
if(!vis[v]){
vis[v]=1;
que.push(v);
}
}
}
}
return flag;
}
int main(){
if(!spfa()) printf("No");
else printf("Yes");
}
DFS
inline int spfa(int u){
vis[u]=1;
for(int i=head[u];i;i=e[i].next)
int v=edge[i].to;
int w=edge[i].weight;
if(dis[v]<dis[u]+w){
dis[v]=dis[u]+w;
if(vis[v])return 0;
if(!spfa(v))return 0;
}
vis[u]=0;
return 1;
}
int main(){;
if(!spfa(0))cout<<"No";
else cout<<"Yes";
return 0;
}
P1250
P1250
——>
https://www.cnblogs.com/BigYellowDog/p/11231829.html
- 建 图
每个部分为一个单位尺寸大小并最多可种一棵树
也就是说一个位置至多只能种1棵树。把它抽象成不等式:
0 <= dis[x] - dis[x - 1] <= 1
- 代 码
#include<queue>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<cstdlib>
using namespace std;
int op,a,b,c,n,dis[10001],l[10001],tot,m,flag;
struct node{
int next,to,w;
}e[60001];
inline void add(int u,int v,int w){
e[++tot]=(node){l[u],v,w};l[u]=tot;return;
};
bool vis[10001];
int read(){
int x = 0; char c = getchar();
while(c < '0' || c > '9') c = getchar();
while(c >= '0' && c <= '9') {
x = x * 10 + c - '0'; c = getchar();
}
return x;
}
inline void spfa(){
queue<int> que;
memset(dis, -0x3f, sizeof(dis));
dis[n + 1] = 0, vis[n + 1] = 1, que.push(n + 1);
while(!que.empty()){
int now = que.front();
que.pop(); vis[now] = 0;
for(int i = l[now]; i != 0; i = e[i].next)
if(dis[now] + e[i].w > dis[e[i].to]){
dis[e[i].to] = dis[now] + e[i].w;
if(!vis[e[i].to])
vis[e[i].to] = 1, que.push(e[i].to);
}
}
}
int main(){
n=read();m=read();
for(int i=1;i<=n;i++){
dis[i]=0x7fffffff;
}
while(m--){
a=read();b=read();op=read();
add(a-1,b,op);
}
dis[0]=0;
int nn=n;
while(nn>=0){add(n+1,nn,0),n--;}//
nn=1;
while(nn<=n){add(nn-1,nn,0),add(nn,nn-1,-1);}//
spfa();
printf("%d",dis[n]);
}