標籤:style blog color os io for 資料 div sp
百科是這樣說的:如果一個系統由n個變數和m個約束條件組成,其中每個約束條件形如xj-xi<=bk(i,j∈[1,n],k∈[1,m]),則稱其為差分約束系統。亦即,差分約束系統是求解關於一組變數的特殊不等式組的方法。
學習差分約束系統之前,必須掌握單源最短路徑的演算法(Bellman-ford、SPFA)。習慣上用SPFA解差分約束的題目。
解題思想有兩種:
假設j > i,
1、由xj - xi >=w得到xj >= xi + w,建立一條從xi->xj的邊權為w的邊。然後用最長路演算法。
2、由xj - xi >=w得到xi <= xj - w,建立一條從xj->xi的邊權為-w的邊。然後用最短路演算法。
在具體建圖的時候,為了避免重複,j+1或者i-1。
實際上,最長路和最短路演算法的區別很小(SPFA模版)。
最長路演算法中dist[]初始化為負無窮,鬆弛的時候是if(dist[v] < dist[u] + Map[u][v]) 。
最短路演算法中dist[]初始化為正無窮,鬆弛的時候是if(dist[v] > dist[u] + Map[u][v]) 。
以具體的題目作為例子吧。
hdu1384
題目大意是:
給出一些區間[ai,bi]和每個區間最少需要ci個點,然後問總共最少需要幾個點滿足所有區間的要求。
由於1<=ai<=bi,所以ai-1或者bi+1都是沒關係的,都是可以的。(下標從0開始和1開始都行,卻不能是負數)
設s[i]是1~i 中需要的點的個數。則
s[j+1]-s[i]>=w。這隻是題目給出的資料所能建的圖。
但是有很多點是沒有連通的。
有隱含條件 0=<s[i+1] - s[i] <=1 。
這樣就可以做題了。
如果選擇建立xj >= xi + w的關係來建圖,就需要用最長路經來解題。dist[]初始化為負無窮。
具體的看代碼:
#include<iostream>#include<cstdio>#include<cstring>#include<queue>#include<algorithm>using namespace std;const int N = 50010, M=150010;const int INF = 0x3f3f3f3f;struct node{ int to, w, next;};node edge[M];int head[N], dist[N], outq[N];bool vis[N];int tot;bool SPFA(int s, int n ){ int i,k; for(i=0;i<=n;i++) dist[i]=-INF; memset(vis,0,sizeof(vis)); memset(outq,0,sizeof(outq)); queue<int > q; while(!q.empty()) q.pop(); vis[s]=1; dist[s]=0; q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); vis[u]=0; outq[u]++; if(outq[u]>n) return 0 ; k=head[u]; while(k>=0) { if(dist[edge[k].to]-edge[k].w<dist[u]) { dist[edge[k].to]=dist[u]+edge[k].w; if(!vis[edge[k].to]) { vis[edge[k].to]=1; q.push(edge[k].to); } } k=edge[k].next; } } return 1;}void addedge(int i, int j ,int w){ edge[tot].to=j; edge[tot].w=w; edge[tot].next=head[i]; head[i]=tot++;}void init(){ memset(head,-1,sizeof(head)); tot=0;}int main(){ //freopen("test.txt","r",stdin); int n,m,i,j,k,w,a,b; while(scanf("%d",&m)!=EOF) { init(); a=INF,b=-INF; for(k=0;k<m;k++) { scanf("%d %d %d",&i,&j,&w); if(a>i) a=i; if(b<j+1) b=j+1; addedge(i,j+1,w); } for(i=a;i<=b;i++) { addedge(i,i+1,0); addedge(i+1,i,-1); } if(SPFA(a,b)) printf("%d\n",dist[b]); } return 0;}
差分約束系統小結