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; }
- poj1201 Intervals(差分约束)
- [POJ1201]Intervals(差分约束)
- poj1201&&hdu1384 Intervals(差分约束)
- POJ1201-Intervals(差分约束)
- POJ1201--差分约束--Intervals
- POJ1201-Intervals(差分约束)
- Intervals poj1201(差分约束)
- (POJ1201)Intervals <差分约束系统-区间约束>
- POJ1201(Hdu1384) Intervals差分约束系统
- poj1201——Intervals(差分约束)
- 【POJ1201】Intervals 差分约束系统
- POJ1201:Intervals(差分约束系统)
- POJ1201 Intervals [差分约束系统 SPFA]
- 【差分约束系统】Intervals POJ1201
- POJ1201 Intervals 【差分约束系统】
- poj1201 Intervals,差分约束问题,spfa
- POJ1201 HDU1384 Intervals【SPFA】【差分约束】
- poj1201 Intervals--单源最短路径&差分约束
- UltraEdit 正则表达式
- 自己系统的关于block size的一些总结
- 动态分配内存 and malloc&new and 数组的动态分配、初始化(memset)和撤销(delete)
- PreferenceStore存不进数据
- C# DropDownList里的树形创建
- poj1201 Intervals(差分约束)
- Mysql数据库备份
- 完整的闪回操作
- 揭秘android界面水平滑动与竖直滑动实现 “第二届 Google 暑期大学生博客分享大赛 - 2011 Android 成长篇 ”
- sogou,想说爱你不容易
- sql中 多个主键 ^_-
- cd命令为何要实现成shell内建命令
- exit、return、_exit、_Exit这几个函数的区别
- 获得查询数据库结果集的记录条数