poj 2983 差分约束学习(用队列超时了,不防用栈试试)
2014-02-14 10:07
363 查看
对于差分约束,写了两道题,有了自己的想法,归纳为3点
1,找出所有条件,其中包括隐含的。
2,对所有条件进行分析,转化为3角不等式。
3,应用最短路,或最长路,进行松弛操作,或判环
差分约束题目有两种,一种求最大值,另外一种求最小值。
(1)当题目是求满足给定不等式的最小值时,就是求图的最长路。
建图方式如下:a – b >= c,对应于边b –> a w(b, a) = c, 然后求最短路;判断条件是:d[v] <= d[u] + w(u, v), 初始化d[]为-INF. 这样求出的d[]就是满足条件的最小值。原因很简单,因为d[i] 是从-INF开始增大,根据不等式逐渐增大,当满足所有不等式时,那么d[i]肯定是最小的了。
(2)当题目是求满足给定不等式的最大值时,就是求图的最短路。
建图方式如下:a – b <= c,对应于边b –> a w(b, a) = c, 然后求最长路;判断条件是:d[v] >= d[u] + w(u, v), 初始化d[]为INF.这样求出的d[]就是最大值。原因和上面一样,因为是从INF逐渐减小的,当满足完所有条件时,就停止。那么d[i]是最大的了。
推荐:spfa算法
1,找出所有条件,其中包括隐含的。
2,对所有条件进行分析,转化为3角不等式。
3,应用最短路,或最长路,进行松弛操作,或判环
差分约束题目有两种,一种求最大值,另外一种求最小值。
(1)当题目是求满足给定不等式的最小值时,就是求图的最长路。
建图方式如下:a – b >= c,对应于边b –> a w(b, a) = c, 然后求最短路;判断条件是:d[v] <= d[u] + w(u, v), 初始化d[]为-INF. 这样求出的d[]就是满足条件的最小值。原因很简单,因为d[i] 是从-INF开始增大,根据不等式逐渐增大,当满足所有不等式时,那么d[i]肯定是最小的了。
(2)当题目是求满足给定不等式的最大值时,就是求图的最短路。
建图方式如下:a – b <= c,对应于边b –> a w(b, a) = c, 然后求最长路;判断条件是:d[v] >= d[u] + w(u, v), 初始化d[]为INF.这样求出的d[]就是最大值。原因和上面一样,因为是从INF逐渐减小的,当满足完所有条件时,就停止。那么d[i]是最大的了。
推荐:spfa算法
#include <iostream> #include <cstdio> #include <cstring> #include <queue> using namespace std; const int M = 100008; int top = 0; struct { int head; }H[M]; struct { int u,v,w,next; }E[M*10]; void add(int u,int v,int w) { E[top].v = v; E[top].w = w; E[top].next = H[u].head; H[u].head = top++; } void init() { top = 0; memset(H,-1,sizeof(H)); memset(E,-1,sizeof(E)); } bool spfa(int f,int n) { int d[M],vis[M],_cnt[M]; memset(d,63,sizeof(d)); d[f] = 0; memset(vis,0,sizeof(vis)); memset(_cnt,0,sizeof(_cnt)); queue <int > q ; q.push(f); vis[f] = 1; _cnt[f]++; while(!q.empty()) { int u = q.front();q.pop(),vis[u] = 0; for(int i = H[u].head;i!=-1;i = E[i].next) { if(d[E[i].v]>d[u]+E[i].w) { d[E[i].v] = d[u] + E[i].w; if(!vis[E[i].v]) { q.push(E[i].v); vis[E[i].v] = 1; _cnt[E[i].v] ++; if(_cnt[E[i].v]>n)return false; } } } } return true; } int main() { int m,n; while(~scanf("%d%d",&n,&m)) { init(); char a[10]; int u,v,w; while(m--) { scanf("%s",a); if(a[0]=='P') { scanf("%d%d%d",&u,&v,&w); add(u,v,-w); add(v,u,w); } else { scanf("%d%d",&u,&v); add(u,v,-1); } } for(int i=1;i<=n;i++)add(0,i,0); spfa(0,n)==true?puts("Reliable"):puts("Unreliable"); } }
相关文章推荐
- 人民日报批“色情业有益无害”说:你家里人知道吗
- 如何理解 iOS Delegate (委托)设计模式
- 在linux中添加字体
- XML中的转义字符
- Android之Bitmap之圆形头像
- 透彻分析反射的基础——Class
- 调试 之gdb thread命令 与 ltrace/strace
- [Object-C语言随笔之一]Mac os 下搭建iOS开发环境
- sshd调优
- 【转】常用算法总结1
- smarty获得当前url的方法分享
- HDU 1251 统计难题
- 禁止select控件选择
- android实现电子时钟效果
- Oracle索引详解
- linux常用命令介绍
- 一些经典书目【转】
- Aircrack-ng官方文档翻译[中英对照]---Airmon-ng
- C++的深拷贝与浅拷贝
- 如何快速在数据库中插入数据