这是一个简单的差分约束题 , 但是通过这题 , 我们能更好的理解 差分约束的 原理和应该注意的地方:
差分约束,其实这是一种线性规划,给出n个不等式的条件 ,问是否能满足所有条件 , 由于我们最短路也是一系列的不等式 ,因此我们就把这些不等式和图、最短路等联系起来。
例如:存在下面3个不等式 : b - a <= k1 , c - b <= k2 , c - a <= k3 ,求c - a的最大值 。
如图:
我们要满足这三个条件 , 等于是要在这个图上求出最短路,其实建立图之后 , 我们求最短路就是求的另一个c 和 a的不等式 , 当所有c 和 a 的不等式都得到 , 并且我们有要满足这所有不等式
, 那么我们就可以得出 c -a的最大值 。
总结:要求最小值时 : 不等式为: a - b >= k1 , 这样建图之后 , 我们就求它们之间的最大路 , 就能得到最小值。
要求最大值时 :不等式为: a - b <= k1 , 这样建图之后 , 我们就求它们之间的最小路 , 就能得到最大值。
怎么建图:由于我们要判断这个图中是否存在负环 , 并且要满足每一个条件 , 所以我们每一条边都应该要有反向边 ,这样才有对比条件。
程序:
差分约束,其实这是一种线性规划,给出n个不等式的条件 ,问是否能满足所有条件 , 由于我们最短路也是一系列的不等式 ,因此我们就把这些不等式和图、最短路等联系起来。
例如:存在下面3个不等式 : b - a <= k1 , c - b <= k2 , c - a <= k3 ,求c - a的最大值 。
如图:
我们要满足这三个条件 , 等于是要在这个图上求出最短路,其实建立图之后 , 我们求最短路就是求的另一个c 和 a的不等式 , 当所有c 和 a 的不等式都得到 , 并且我们有要满足这所有不等式
总结:要求最小值时 : 不等式为: a - b >= k1 , 这样建图之后 , 我们就求它们之间的最大路 , 就能得到最小值。
怎么建图:由于我们要判断这个图中是否存在负环 , 并且要满足每一个条件 , 所以我们每一条边都应该要有反向边 ,这样才有对比条件。
程序:
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <queue>
using namespace std;
#define maxn 1010
#define INF 0xfffffff
int grap[maxn][maxn];
int dist[maxn] , n , m;
int cost[maxn] , maxsum ;
void init()
{
int i ,j;
for(i = 0; i<= n; i++)
for(j = 0; j<= n; j++)
grap[i][j] =INF;
for(i = 0; i<= n; i++)
grap[i][i] =0;
}
int SPFA()
{
int i ,pre[maxn] , vis[maxn];
queue<int>q;
for(i = 0; i<= n; i++)
dist[i] =INF;
memset(vis ,0 , sizeof(vis));
memset(pre ,0 , sizeof(pre));
vis[n] +=1;
dist[n] =0;
q.push(n);
while(!q.empty())
{
int u =q.front(); q.pop();
pre[u] =0;
for(i = 0; i<= n ; i++)
if(dist[i]> dist[u]+grap[u][i])
{
dist[i] =dist[u]+grap[u][i];
if(!pre[i])
{
pre[i] = 1 ,q.push(i);
if(++vis[i]> (n+1))
{
// cout<<i<<endl;
return0;
}
}
}
}
return 1;
}
int main()
{
while(scanf("%d %d" , &n , &m) != EOF)
{
init();
cost[0] =0;
// maxsum =0;
int i , x ,y , z;
for(i = 1; i<= n; i++)//要满足每个大营都不超过最大值 , 那么我们就必须为每个大营都建立边,(反向正向都必须要建)
{
scanf("%d" ,&x);
cost[i] =x+cost[i-1];
grap[i-1][i]= x;
grap[i][i-1]= 0;
// maxsum +=c[i];
}
for(i = 1; i<= m; i++)//这是输入的边 , 同时我们也要建立输入边的反向边 , 这样存在对比性
{
scanf("%d %d%d" , &x , &y , &z);
grap[y][x-1]= -z;
grap[x-1][y]= cost[y]-cost[x-1];
}
x =SPFA();
if(x ==0) printf("Bad Estimations\n");
else
cout<<dist[n]-dist[0]<<endl;
}
return0;
}