查分约束系统
来源:互联网 发布:linux删除一个目录 编辑:程序博客网 时间:2024/04/28 20:57
查分约束系统
定义
如果一个系统由n个变量和m个约束条件组成,形成m个形如ai-aj≤k的不等式(i,j∈[1,n],k为常数),则称其为差分约束系统(system of difference constraints)。亦即,差分约束系统是求解关于一组变量的特殊不等式组的方法.
观察xj-xi<=bk,会发现它类似最短路中的三角不等式d[v]<=d[u]+w[u,v],即d[v]-d[u]<=w[u,v]。因此,以每个变量xi为结点,对于约束条件xj-xi<=bk,连接一条边(i,j),边权为bk。我们再增加一个源点s,s与所有定点相连,边权均为0。对这个图,以s为源点运行Bellman-ford算法(或SPFA算法),最终{d[ i]}即为一组可行解。
例如,考虑这样一个问题,寻找一个5维向量x=(xi)以满足:
这一问题等价于找出未知量xi,i=1,2,…,5,满足下列8个差分约束条件:
x1-x2≤0x1-x5≤-1x2-x5≤1x3-x1≤5x4-x1≤4x4-x3≤-1x5-x3≤-3x5-x4≤-3
该问题的一个解为x=(-5,-3,0,-1,-4),另一个解y=(0,2,5,4,1),这2个解是有联系的:y中的每个元素比x中相应的元素大5。
引理:设x=(x1,x2,…,xn)是差分约束系统Ax≤b的一个解,d为任意常数。则x+d=(x1+d,x2+d,…,xn+d)也是该系统Ax≤b的一个解。
算法核心思路,寻找约束关系,差分约束小于等于最短路,大于等于最长路.用spfa或者bellman_ford算法求解
队列优化的spfa算法
void spfa(int start,int n){ int top = 0; for(int v = 1;v<=n;v++){ if(v==start){ Q[top++] = v; vis[v] = true; d[v] = 0; } else{ vis[v] = false; d[v] = inf; } } while (top!=0){ int u = Q[--top]; vis[u] = false; for(int i = head[u];i!=-1;i=es[i].next){ int v = es[i].to; if(d[v]>d[u]+es[i].cost){ d[v] = d[u]+es[i].cost; if(!vis[v]){ vis[v] = true; Q[top++] = v; } } } }}
bellman_ford算法
struct Edge{ int from; int to; int cost;}es[max_v];void addEdge(int a,int b,int c){ es[tol].from = a; es[tol].to = b; es[tol].cost = c; tol++;}void shortest_path(int s){ for(int i = 0;i<=n;i++){ d[i] = inf; } d[s] = 0; int times = 0; bool update = true; while (times<n&&update){ update = false; for(int i = 0;i<m;i++){ Edge now = es[i]; if(d[now.from]!=inf&&d[now.to]>d[now.from]+now.cost){ d[now.to] = d[now.from]+now.cost; //cout<<now.to<<" "<<d[now.to]<<endl; update = true; } } times++; } /*if(d[n]==inf){ cout<<-2<<endl; return; } if(times==n){ cout<<-1<<endl; } else{ cout<<d[n]<<endl; }*/}
poj1201 Intervals (最长路)
题目链接 poj1201
//// Created by 王若璇 on 16/6/1.//#include <iostream>#include <cstring>#include <cstdio>#include <queue>#include <algorithm>using namespace std;const int max_n = 200500;const int inf = 0x3f3f3f3f; //差分约束小于等于最短路,大于等于最长路.int head[max_n];int d[max_n];struct Edge{ int to; int cost; int next;}es[max_n];int tol = 0;int up = 0;int down = 0x3f3f3f3f;queue<int> qu;bool vis[max_n];int n;void addEdge(int a,int b,int c){ es[tol].to = b; es[tol].cost = c; es[tol].next = head[a]; head[a] = tol++;}void spfa(int s,int t){ for(int i = down;i<=up;i++){ d[i] = -inf; } while (!qu.empty()){ qu.pop(); } qu.push(s); d[s] = 0; vis[s] = true; while (!qu.empty()){ int u = qu.front(); qu.pop(); vis[u] = false; for(int i = head[u];i!=-1;i = es[i].next){ int v = es[i].to; if(d[v]<d[u]+es[i].cost){ d[v] = d[u]+es[i].cost; if(!vis[v]){ vis[v] = true; qu.push(v); } } } }}int main(){ ios::sync_with_stdio(false); cin.tie(NULL); while (cin>>n){ memset(head,-1, sizeof(head)); for(int i = 0;i<n;i++){ int a,b,c; cin>>a>>b>>c; addEdge(a-1,b,c); up = max(up,b); down = min(down,a-1); } for(int i = down;i<up;i++){ addEdge(i,i+1,0); addEdge(i+1,i,-1); } spfa(down,up); cout<<d[up]-d[down]<<endl; } return 0;}
poj3159 (最短路)
题目链接 poj3159
//// Created by 王若璇 on 16/5/31.//#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#include <queue>#include <vector>using namespace std;const int max_n = 30030;const int max_v = 150000;const int inf = 0x3f3f3f3f;int d[max_n];//int c[max_n][max_n];int n,m;int head[max_n];bool vis[max_n];int Q[max_n];struct Edge{ int to; int cost; int next;};Edge es[max_v];int tol;void add(int a,int b,int v){ es[tol].to = b; es[tol].cost = v; es[tol].next = head[a]; head[a] = tol++;}void spfa(int start,int n){ int top = 0; for(int v = 1;v<=n;v++){ if(v==start){ Q[top++] = v; vis[v] = true; d[v] = 0; } else{ vis[v] = false; d[v] = inf; } } while (top!=0){ int u = Q[--top]; vis[u] = false; for(int i = head[u];i!=-1;i=es[i].next){ int v = es[i].to; if(d[v]>d[u]+es[i].cost){ d[v] = d[u]+es[i].cost; if(!vis[v]){ vis[v] = true; Q[top++] = v; } } } }}int main(){ //ios::sync_with_stdio(false); //cin.tie(NULL); while (scanf("%d%d",&n,&m)!=EOF){ //memset(vis,0, sizeof(vis)); memset(head,-1,sizeof(head)); tol = 0; while (m--){ int a,b,c; scanf("%d%d%d",&a,&b,&c); add(a,b,c); } spfa(1,n); //cout<<d[n]<<endl; printf("%d\n",d[n]); //cout<<dijstra(1,n)<<endl; } return 0;}
0 0
- 查分约束系统
- 查分约束系统
- POJ2983 查分约束系统
- 查分约束系统详解
- 7.1 查分约束系统
- 查分约束系统板子
- POJ1201 Intervals(查分约束系统)
- bzoj2330 SCOI2011糖果 查分约束系统
- poj3169----查分约束系统的应用
- 查分约束
- 查分约束uva
- poj2983(查分约束)
- bzoj 1202: [HNOI2005]狡猾的商人 查分约束系统
- 查分约束的总结
- poj 1364 查分约束
- 最短路&查分约束
- POJ1201(查分约束)
- hdu 1384 查分约束
- 风力发电机
- MySQL的 SELECT语句完整语法
- Java学习笔记(6)Methods
- 系统托盘支持
- spring mvc对异步请求的处理
- 查分约束系统
- 6月20日--swift3常量与变量
- 分析小米家庭智能套装
- Android如何高效加载大图
- android NDK实现
- 自行车码表CPU选型
- 【Maven】快速走进Maven的世界
- Cortex指令集相比ARM的优势
- 中断驱动的自行车码表