poj1201 Intervals(差分约束)

来源:互联网 发布:java socket建立长连接 编辑:程序博客网 时间:2024/04/30 01:05

 差分约束第一题,差分约束就是解一系列的形如x1-x2<=(>=)a的不等式,由于移项之后为x1<=(>=)x2+a和最短路径的dist[i] <(>) dist[u] + mapp[u][i]联系 起来,故可以用最短路bellmanford和SPFA求解
显然dist[i]和dist[u]都为方程的解,根据大于或者小于可以以最短路径或者最长路径求解
我们举最短路径为例
因为是求的最短路径,那么结果可以保证dist[i] <= dist[u]+mapp[u][i],那么对此不等式移向可以得到dist[i] - dist[u] <= mapp[u][i],在最短路中,i,u分别为两个节点,而且存在一条u->i的路径。
现在回到POJ1201,输入样例如下:
5
3 7 3
8 10 3
6 8 1
1 3 1
10 11 1
设第i个点以前被选中的数有Si个,那么对于输入的一段闭区间[a, b]中有c[i]个数被选中,就有以下不等式方程:
(1)Sb[i] - Sa[i] >=  c[i];
(2)1 >= Si-S(i-1) >= 0;
由于我们是以最短路径为例,故将上述不等式改为
(1)Sa[i] - Sb[i] <=  -1*c[i];
(2)Si - S(i-1) <= 1;
(3)S(i-1) - S(i) <= 0;
据上述差分约束方程求解可以建图,对第一个输入,可以建图7->2,权值为-3,这样依次将全部输入建图,但是因为最后的结果可能是一个非连通图,所以还要根据上述不等式对每一个[i, i+1]建图,建图完后一次SPFA就可以求解
注意:最终答案是-dist[minn-1],最长路径则为dist[maxx+1];
附AC代码:
 (最短路径)

#include <iostream>#include <vector>#include <queue>using namespace std;struct node{       int num;       int value;       };const int size = 51000;bool inque[size];int dist[size];vector <node> mapp[size];int minn, maxx;void init(){     for (int i = 0; i < size; i ++){         mapp[i].clear();         }     }void SPFA(int s1){     queue <node> que;     for (int i = minn; i <= maxx; i ++){         inque[i] = false;         dist[i] = 100000000;         }     node s;     s.num = s1;     s.value = 0;     que.push(s);     dist[s.num] = 0;     inque[s.num] = true;     while (!que.empty()){           node e = que.front();           inque[e.num] = false;           que.pop();           for (int i = 0; i < mapp[e.num].size(); i ++){               node ee = mapp[e.num][i];               if (dist[ee.num] > dist[e.num] + ee.value){                  dist[ee.num] = dist[e.num] + ee.value;                  if (!inque[ee.num]){                     ee.value = dist[ee.num];                     que.push(ee);                     inque[ee.num] = true;                                      }                                  }               }           }         }int main(){    int n;    while (scanf("%d", &n) != EOF){          init();          node a, b;          minn = INT_MAX, maxx = -1;          for (int i = 0; i < n; i ++){              scanf("%d%d%d", &a.num, &b.num, &a.value);              minn = minn > a.num? a.num : minn;              maxx = maxx < b.num? b.num : maxx;              a.num --;              a.value*=-1;              mapp[b.num].push_back(a);               }               for (int i = minn; i <= maxx; i ++){              a.num = i,  a.value = 0;              mapp[i+1].push_back(a);              a.num = i+1,  a.value = 1;              mapp[i].push_back(a);          }          SPFA(maxx);          printf("%d\n", -dist[minn-1]);    }    return 0;    }/*(最长路径)*/#include <iostream>#include <vector>#include <queue>using namespace std;struct node{       int num;       int value;       };const int size = 51000;bool inque[size];int dist[size];vector <node> mapp[size];int minn, maxx;void init(){     for (int i = 0; i < size; i ++){         mapp[i].clear();         }     }void SPFA(int n, int s1){     queue <node> que;     for (int i = minn; i <= maxx; i ++){         inque[i] = false;         dist[i] = -100000000;         }     node s;     s.num = s1;     s.value = 0;     que.push(s);     dist[s.num] = 0;     inque[s.num] = true;     while (!que.empty()){           node e = que.front();           inque[e.num] = false;           que.pop();           for (int i = 0; i < mapp[e.num].size(); i ++){               node ee = mapp[e.num][i];               if (dist[ee.num] < dist[e.num] + ee.value){                  dist[ee.num] = dist[e.num] + ee.value;                  if (!inque[ee.num]){                     ee.value = dist[ee.num];                     que.push(ee);                     inque[ee.num] = true;                                      }                                  }               }           }         }int main(){    int n;    while (scanf("%d", &n) != EOF){          init();          node a, b;          minn = INT_MAX, maxx = -1;          for (int i = 0; i < n; i ++){              scanf("%d%d%d", &a.num, &b.num, &b.value);              minn = minn > a.num? a.num : minn;              maxx = maxx < b.num? b.num : maxx;              b.num ++;              mapp[a.num].push_back(b);               }                  for (int i = minn; i <= maxx; i ++){              a.num = i+1,  a.value = 0;              mapp[i].push_back(a);              a.num = i,  a.value = -1;              mapp[i+1].push_back(a);          }          SPFA(maxx, minn);          printf("%d\n", dist[maxx+1]);    }    return 0;    }


 

原创粉丝点击