差分约束-Vijos-p1094
来源:互联网 发布:贴片电容标称值算法 编辑:程序博客网 时间:2024/06/03 12:38
还没有对差分约束有了解的同学我推荐一篇大牛的博客,它的博客都讲的比较好。
博客链接:夜深人静写算法-差分约束
上面的大神讲的很详细,相信认真看了就会懂。
我说说我对差分约束的理解。我感觉差分约束就是将问题转换成一些不等式组,然后通过这些不等式组建边,最后就转换成求最短路、最长路、最大值、最小值等问题。(个人理解)
现在我以Vijos的p1094为例(感觉是一道不错的模版题)
题目链接:https://vijos.org/p/1094
题意
就是给出一些节点的大小关系(>,<,=),让你求出最小的k,使得所有节点填上[0,k]之间的数能满足所有关系,不存在就输出NO。
题解
感觉基本上算是裸的差分约束,直接不等式建边。比如给出1>2即1-2>0即1-2>=1,所以可以建一条2指向1的权值为1的边。(这里数字都是节点编号)同理,对于1<2可以建一条1指向2的权值为1的边,对于1=2可以建一条1到2的权值为0的双向边,建完边后就是一个图。因为我们要满足所有的不等式,而不等式能经过一些变换得到新不等式,最后所有不等式基本都是a-b>=k的类型,所以我们求的就是所有不等式中k的最大值,对应的就是图中的最长路。(因为那个不等式满足了,其它所有不等式都能找到对应值满足,就像在图中最长路上节点依次填入0-k,其它节点肯定能填入0-k之间的值使之满足)
这里就遇到一个问题了,因为不知道起始点即源点,所以我们不好跑单源最长路。怎么解决?想这种情况我也遇到过几次了,一般可以自己新建一个点当源点,然后与其它节点之间添加一些合适的边就可解决问题。对于这一题我是指定0作为源点,然后与其它所有点之间建一条0指向它的边即可。(不能是双向边,不然会出现正权环)最后SPFA跑一遍最长路就可以了。
#include <bits/stdc++.h>using namespace std;const int INF = -0x3f3f3f3f;const int maxn = 1e3+5;int n,m;int dist[maxn],vis[maxn],inqueue_num[maxn];struct Edge{ int to,len;};vector<Edge> edge[maxn];void init(){ memset(dist,INF,sizeof(dist)); memset(vis,0,sizeof(vis)); memset(inqueue_num,0,sizeof(inqueue_num)); for(int i=0;i<=n;i++) edge[i].clear();}bool SPFA(){ int x; dist[0]=0,vis[0]=1,inqueue_num[0]++; queue<int>q; q.push(0); while(!q.empty()) { x = q.front(),q.pop(); vis[x]=0; for(int i=0;i<edge[x].size();i++) { int y=edge[x][i].to; int len=edge[x][i].len; if(dist[y]<dist[x]+len) { dist[y] = dist[x]+len; if(!vis[y]) { q.push(y); vis[y]=1; inqueue_num[y]++; if(inqueue_num[y]>=n) return false; } } } } return true;}int main(){ init(); scanf("%d%d",&n,&m); int u,v,c; Edge tmp; while(m--) { scanf("%d%d%d",&u,&v,&c); if(c==1) { tmp.to=u,tmp.len=1; edge[v].push_back(tmp); } else if(c==0) { tmp.to=v,tmp.len=0; edge[u].push_back(tmp); tmp.to=u,tmp.len=0; edge[v].push_back(tmp); } else { tmp.to=v,tmp.len=1; edge[u].push_back(tmp); } } for(int i=1;i<=n;i++) { tmp.to=i,tmp.len=0; edge[0].push_back(tmp); } if(SPFA()) { int ans=INF; for(int i=1;i<=n;i++) ans = max(ans,dist[i]); printf("%d\n",ans); } else printf("NO\n"); return 0;}
- 差分约束-Vijos-p1094
- vijos区间(差分约束)
- vijos关系运算符(差分约束)
- 【图-差分约束】 差分约束
- 差分约束系统
- 差分约束系统
- 差分约束系统
- 差分约束系统
- POJ_1364_差分约束
- 差分约束系统
- 差分约束
- 差分约束 模板
- 差分约束系统
- 差分约束系统
- 差分约束系统
- Poj1275 差分约束
- 【差分约束系统】
- poj1364 差分约束
- 11、Bootstrap--图片样式、辅助类样式及CSS组件
- JavaScript对象中的属性能否有对象类型
- 粒子系统-烟花效果的实现
- JavaWeb(1)_doGet与doPost区别
- TX2-安装Caffe深度学习框架
- 差分约束-Vijos-p1094
- leetcode之Insert Delete GetRandom O(1) 问题
- 2017 Multi-University Training Contest
- Maven教程
- 二叉树的深度优先遍历(栈)和广度优先遍历(队列)
- Linux tar命令
- 【BZOJ】1598 [Usaco2008 Mar]牛跑步 k短路(最短路径+A*)
- 会话技术
- MyBatis注解