差分约束系统专题
来源:互联网 发布:sql 微整型 编辑:程序博客网 时间:2024/06/05 17:42
1、教程
书籍:算法导论p370、黑书
论文:http://wenku.baidu.com/view/c37d3486bceb19e8b8f6baae.html
博客:http://www.cnblogs.com/wangyaohui/articles/2134040.html
http://www.cppblog.com/mythit/archive/2009/06/04/86756.html
http://www.cnblogs.com/litstrong/archive/2010/08/08/1795268.html(先这些,找到好的再换)
2、一些题目
hdu:1384 1529 1531 1534 3440 3592 3666
poj:1201 1275 1364 2983 3159 3169
3、解题报告
http://972169909-qq-com.iteye.com/blog/1185527
http://blog.csdn.net/l04205613/article/details/6660930
poj1201 & hdu1384
先定义s[i+1]表示0-i中选的个数,于是
1、题意:[ai,bi]中至少ci个可以表示为s[bi+1]-s[ai]>=ci
2、定义:1>=s[i+1]-s[i]>=0,也就是i选与不选两种情况
最终s[max+1]-s[min]即为所求
差分约束系统有求最长路,最短路两种方式
1、最长路:s[bi+1]-s[ai]>=ci
2、最短路:s[ai]-s[bi+1]<=-ci
hdu 1529 & poj1275
x[i] 表示第i时刻选定的人数
n[i] 表示第i时刻可选的人数
r[i] 表示第i时刻需要的人数
x[i] <= n[i]
x[i]+x[i-1]+...+x[i-7] >= r[i]
令s[i]=x[0]+x[1]+...+x[i]
0<=s[i]-s[i-1]<=n[i], i=1,2..23
s[0]<=n[0]
s[i]-s[i-8]>=r[i], i=8,9..23
s[23]+s[i]-s[i+16]>=r[i], i=0,1..7
整理得
s[i]-s[i-1]>=0, i=1,2..23
s[i-1]-s[i]>=-n[i], i=1,2..23
s[0]>=-n[0]
s[i]-s[i-8]>=r[i] , i=8,9..23
s[i]-s[i+16]>=r[i]-s[23], i=0,1..7
求min(s[23])
代码1:
#include<cstdio>#include<cstring>#include<climits>#include<iostream>#include<queue>#include<vector>using namespace std;#define min(a,b) a<b?a:b#define max(a,b) a>b?a:bconst int N = 51000;struct node{ int v, x; };vector<node> edg[N];int vis[N], tim[N], dis[N];queue<int> q;int s, t, o, n;void input(){ node tmp; int u, v, x; for(x=0; x<N; ++x) edg[x].clear(); s=INT_MAX; t=INT_MIN; // add input edge while(n--) { scanf("%d%d%d", &u, &v, &x); s=min(s, u); t=max(t, v); tmp.v=v+1; tmp.x=x; edg[u].push_back(tmp); } t++; // add -1 edge for(u=t; u>s; --u) { tmp.v=u-1; tmp.x=-1; edg[u].push_back(tmp); } // add 0 edge for(u=s; u<t; ++u) { tmp.v=u+1; tmp.x=0; edg[u].push_back(tmp); }}void spfa(){ int i, u, v, x, m; memset(vis, 0, sizeof(vis)); for(i=s; i<=t; ++i) dis[i]=-INT_MAX; while(!q.empty()) q.pop(); dis[s]=0; q.push(s); vis[s]=1; while(!q.empty()) { u=q.front(); q.pop(); vis[u]=0; m=edg[u].size(); for(i=0; i<m; ++i) { v=edg[u][i].v; x=edg[u][i].x; if(dis[v]<dis[u]+x) { dis[v]=dis[u]+x; if(!vis[v]) { vis[v]=1; q.push(v); } } } } printf("%d\n", dis[t]-dis[s]);}int main(){ while(~scanf("%d",&n)) { input(); spfa(); } return 0;}
代码2:
#include<cstdio>#include<cstring>#include<climits>#include<iostream>#include<queue>#include<vector>using namespace std;#define min(a,b) a<b?a:b#define max(a,b) a>b?a:bconst int N = 51000;struct node{ int v, x; };vector<node> edg[N];int vis[N], tim[N], dis[N];queue<int> q;int s, t, o, n;void input(){ node tmp; int u, v, x; for(x=0; x<N; ++x) edg[x].clear(); s=INT_MAX; t=INT_MIN; // add input edge while(n--) { scanf("%d%d%d", &v, &u, &x); u++; s=min(s, v); t=max(t, u); tmp.v=v; tmp.x=-x; edg[u].push_back(tmp); } // add 0 edge for(u=t; u>s; --u) { tmp.v=u-1; tmp.x=0; edg[u].push_back(tmp); } // add 1 edge for(u=s; u<t; ++u) { tmp.v=u+1; tmp.x=1; edg[u].push_back(tmp); } u=o=t+1; tmp.x=0; // add o-> x for(x=s; x<=t; ++x) { tmp.v=x; edg[u].push_back(tmp); } n=t-s+2;}void spfa(){ int i, u, v, x, m; memset(vis, 0, sizeof(vis)); memset(tim, 0, sizeof(tim)); for(i=s; i<=t; ++i) dis[i]=INT_MAX; while(!q.empty()) q.pop(); dis[o]=0; q.push(o); vis[o]=tim[o]=1; while(!q.empty()) { u=q.front(); q.pop(); vis[u]=0; m=edg[u].size(); for(i=0; i<m; ++i) { v=edg[u][i].v; x=edg[u][i].x; if(dis[v]>dis[u]+x) { dis[v]=dis[u]+x; if(!vis[v]) { vis[v]=1; q.push(v); tim[v]++; if(tim[v]>n) while(!q.empty()) q.pop(); } } } } printf("%d\n", dis[t]-dis[s]);}int main(){ while(~scanf("%d",&n)) { input(); spfa(); } return 0;}
- 差分约束系统专题
- 差分约束专题
- 差分约束系统
- 差分约束系统
- 差分约束系统
- 差分约束系统
- 差分约束系统
- 差分约束系统
- 差分约束系统
- 差分约束系统
- 【差分约束系统】
- 差分约束系统
- 差分约束系统
- 差分约束系统
- ##差分约束系统##
- 差分约束系统
- 差分约束系统
- 差分约束系统
- WinForm仿QQ系统消息框的API实现
- cin.get(),cout.put(),cin.eof()的应用案例
- 数据库水平分割 垂直分割 库表散列简述
- EXISTS 用法
- 测试存在风险及解决方法
- 差分约束系统专题
- 读《某石化公司SAP项目存储管理和备份方案》有感
- 软件缺陷的原则
- 获取Android手机中所有的短信
- 根据 T-Code 获取相关的 User-Exit / Finding the user-exits of a SAP transaction code
- 一次表空间配额错误的处理ORA-01536
- 2.14
- java正则表达式
- 文档测试