差分約束系統小結

來源:互聯網
上載者:User

標籤: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;}

 

 

 

  

  

差分約束系統小結

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.