标签:
下面是差分约束系统的详细介绍,以及解决方法~ 摘抄自 xuezhongfenfei(他好像也是转的....)
差分约束系统
X1 - X2 <= 0
X1 - X5 <= -1
X2 - X5 <= 1
X3 - X1 <= 5
X4 - X1 <= 4
X4 - X3 <= -1
X5 - X3 <= -3
X5 - X4 <= -3
不等式组(1)
这个不等式组要么无解,要么就有无数组解。因为如果有一组解{X1, X2, ..., Xn}的话,那么对于任何一个常数k,{X1 + k, X2 + k, ..., Xn + k}肯定也是一组解,因为任何两个数同时加一个数之后,它们的差是不变的,那么这个差分约束系统中的所有不等式都不会被破坏。
d(v) <= d(u) + w(u, v)
X1 - X0 <= 0
X2 - X0 <= 0
X3 - X0 <= 0
X4 - X0 <= 0
X5 - X0 <= 0
不等式组(2)
图1 
X0 = 0
d(v) >= d(u) + w(u, v)
也就是d(v) - d(u) >= w(u, v)
最近几天系统得学习了一些差分约束系统的原理,特此记录如下:
所谓差分约束系统,是指一组不定方程(A,x,T,b),其中A的每行有一个1,一个-1,其余为0,x为解向量,T为<=或>=组成的向量,b为约束矢量。具体来说,就是每行都具有 xi-xj >=|<= bi 的形式。约束的目标是使得目标函数xt-xs最大或最小。
这是典型的线性规划的个案,但是也可以转化为图论来做,利用最短路(或最长路)方法可以实现高效的解决方案。
SPFA的介绍:
http://blog.csdn.net/u013382399/article/details/44227003
这样最后再附上自己的代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
using namespace std;
const int maxn = 110;
const int INF = 0x3f3f3f3f;
struct Edge{
int u,v,w,next;
}edge[maxn*maxn];
int d[maxn],in[maxn],next[maxn];
bool vis[maxn];
int tot;
int n,m;
queue<int> q;
void addEdge(int u,int v,int w){
edge[tot].u = u;
edge[tot].v = v;
edge[tot].w = w;
edge[tot].next = next[u];
next[u] = tot++;
}
bool spfa(int size){
int u,v;
while(!q.empty()) q.pop();
memset(in,0,sizeof(in));
memset(vis,0,sizeof(vis));
fill(d,d+size,INF);
d[n+1] = 0;vis[n+1] = true;in[n+1] = 1;
q.push(n+1);
while(!q.empty()){
u = q.front();vis[u] = false; q.pop();
for(int i = next[u]; i != -1; i = edge[i].next){
v = edge[i].v;
if(d[u] + edge[i].w < d[v]){
d[v] = d[u] + edge[i].w;
if(!vis[v]){
vis[v] = true;
in[v] ++;
if(in[v] > size) return false;
q.push(v);
}
}
}
}
return true;
}
int main(){
int si,ni,ki;
char oi[5];
while(scanf("%d",&n)){
if(n == 0) break;
scanf("%d",&m);
memset(next,-1,sizeof(next));
tot = 0;
///自己创造一个超级原点,建立与其他点链接的边(使其与其他点相连接)
///因为SPFA没有办法处理不连通的图
for(int i = 0; i <= n; i++){
addEdge(n+1,i,0);///我让点n+1作为一个超级源点,其余各节点的边权是0
}
for(int i = 1; i <= m; i++){
scanf("%d%d%s%d",&si,&ni,oi,&ki);
if(oi[0] == 'g') addEdge(si+ni,si-1,-(ki+1));
if(oi[0] == 'l') addEdge(si-1,si+ni,ki-1);
}
if (spfa(n + 2)) printf("lamentable kingdom\n");///总共有n+2个点
else printf("successful conspiracy\n");
}
return 0;
}
UVa 515 - King (差分约束系统 + SPFA求带负权最短路)
标签:
原文地址:http://blog.csdn.net/u013382399/article/details/44226011