poj 1201 (差分约束系统)
来源:互联网 发布:java工作经验的描述 编辑:程序博客网 时间:2024/06/03 15:05
题意:给你n条线段,形如a b c,代表起点,终点以及最少从线段上取多少个点,问你在满足所有约束条件下最多能从所有线段上取多少个点。
分析:为了构造约束条件,首先想象有一个源点,d[x]就表示从源点到x点这个范围内取的点数,于是对每一条线段a b c,有d[b]-d[a]>=c,但后来发现这样不行,例如有1 3 3,3 5 2,按前面的构造方法求出来的解是5,但正确的解应该是4,因为线段在3点处重叠了。为了解决这个问题,可将每条线段的区间构造为左闭右开区间,即[a,b+1),而且这样仍满足题意。但只这样的话约束条件还不够,构建的图不连通,于是还要寻找其它的约束条件。其实确实有点不好想,我也是看网上大神讲了后才知道的,题目中隐含的约束条件:在区间[i,i+1)内,最少取0个点,最多取1个点,即0<=d[i+1]-d[i]<=1,于是得到以下全部约束条件:
d[b+1]-d[a]>=c;
d[i]-d[i+1]>=-1;
d[i+1]-d[i]>=0;
另外,读输入时,记录下出现的点里面的最小点min和最大点max,源点就设为min点。
接下来建图求最长路就行了。输出d[max]即为解。
代码如下:
#include <cstdio>#include <stack>#include <set>#include <iostream>#include <string>#include <vector>#include <queue>#include <functional>#include <cstring>#include <algorithm>#include <cctype>#include <string>#include <map>#include <iomanip>#include <cmath>#define LL long long#define ULL unsigned long long#define SZ(x) (int)x.size()#define Lowbit(x) ((x) & (-x))#define MP(a, b) make_pair(a, b)#define MS(arr, num) memset(arr, num, sizeof(arr))#define PB push_back#define F first#define S second#define ROP freopen("input.txt", "r", stdin);#define MID(a, b) (a + ((b - a) >> 1))#define LC rt << 1, l, mid#define RC rt << 1|1, mid + 1, r#define LRT rt << 1#define RRT rt << 1|1#define BitCount(x) __builtin_popcount(x)#define BitCountll(x) __builtin_popcountll(x)#define LeftPos(x) 32 - __builtin_clz(x) - 1#define LeftPosll(x) 64 - __builtin_clzll(x) - 1const double PI = acos(-1.0);const int INF = 0x3f3f3f3f;using namespace std;const double eps = 1e-8;const int MAXN = 300 + 10;const int MOD = 1000007;const int M=20010;const int N=1000010;const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };typedef pair<int, int> pii;int n,m,minn,maxx,d[N],q[N];int e,w[N],u[N],v[N],first[N],next[N];bool vis[N];void add(int a,int b,int c){ u[e]=a; v[e]=b; w[e]=c; next[e]=first[a]; first[a]=e++;}void build(){ int i,j,a,b,c; e=0; minn=INF; maxx=-INF; MS(first,-1); for (i=0;i<n;i++) { scanf("%d%d%d",&a,&b,&c); minn=min(a,minn); maxx=max(b+1,maxx); add(a,b+1,c); } for (i=minn;i<maxx;i++){ add(i,i+1,0); add(i+1,i,-1); }}int spfa(){ int i,j; int right,left; int t; right=left=0; MS(vis,false); for (i=minn;i<=maxx;d[i++]=-INF); d[minn]=0; q[right++]=minn; while(left<right) { t=q[left++]; vis[t]=false; for (i=first[t];i!=-1;i=next[i]){ if (d[v[i]]<d[u[i]]+w[i]){ d[v[i]]=d[u[i]]+w[i]; if (!vis[v[i]]){ q[right++]=v[i]; vis[v[i]]=true; } } } } //for (i=minn;i<=maxx;cout<<d[i++]<<" "); cout<<endl; return d[maxx];}int main(){ int i,j; while(~scanf("%d",&n)) { build(); int t=spfa(); printf("%d\n",t); }}
这题也可以通过求最短路解决,但是要注意以max为源点来求,输出-d[min]为解(其实我也不明白为什么要这样)。
代码如下:
#include <cstdio>#include <stack>#include <set>#include <iostream>#include <string>#include <vector>#include <queue>#include <functional>#include <cstring>#include <algorithm>#include <cctype>#include <string>#include <map>#include <iomanip>#include <cmath>#define LL long long#define ULL unsigned long long#define SZ(x) (int)x.size()#define Lowbit(x) ((x) & (-x))#define MP(a, b) make_pair(a, b)#define MS(arr, num) memset(arr, num, sizeof(arr))#define PB push_back#define F first#define S second#define ROP freopen("input.txt", "r", stdin);#define MID(a, b) (a + ((b - a) >> 1))#define LC rt << 1, l, mid#define RC rt << 1|1, mid + 1, r#define LRT rt << 1#define RRT rt << 1|1#define BitCount(x) __builtin_popcount(x)#define BitCountll(x) __builtin_popcountll(x)#define LeftPos(x) 32 - __builtin_clz(x) - 1#define LeftPosll(x) 64 - __builtin_clzll(x) - 1const double PI = acos(-1.0);const int INF = 0x3f3f3f3f;using namespace std;const double eps = 1e-8;const int MAXN = 300 + 10;const int MOD = 1000007;const int M=20010;const int N=1000010;const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };typedef pair<int, int> pii;int n,m,minn,maxx,d[N];int e,w[N],u[N],v[N],first[N],next[N];bool vis[N];void add(int a,int b,int c){ u[e]=a; v[e]=b; w[e]=c; next[e]=first[a]; first[a]=e++;}void build(){ int i,j,a,b,c; e=0; minn=INF; maxx=-INF; MS(first,-1); for (i=0;i<n;i++) { scanf("%d%d%d",&a,&b,&c); minn=min(a,minn); maxx=max(b+1,maxx); add(b+1,a,-c); } for (i=minn;i<maxx;i++){ add(i,i+1,1); add(i+1,i,0); }}int spfa(){ int i,j; int right,left; int t, q[N]; right=left=0; MS(vis,false); for (i=minn;i<=maxx;d[i++]=INF); d[maxx]=0; q[right++]=maxx; while(left<right) { t=q[left++]; vis[t]=false; for (i=first[t];i!=-1;i=next[i]){ if (d[v[i]]>d[u[i]]+w[i]){ d[v[i]]=d[u[i]]+w[i]; if (!vis[v[i]]){ q[right++]=v[i]; vis[v[i]]=true; } } } } //for (i=minn;i<=maxx;cout<<d[i++]<<" "); cout<<endl; return -d[minn];}int main(){ int i,j; while(~scanf("%d",&n)) { build(); printf("%d\n",spfa()); }}
0 0
- Poj 1201 (差分约束系统)
- POJ 1201 Intervals 差分约束系统
- POJ 1201 Intervals 差分约束系统
- poj 1201 (差分约束系统)
- POJ 1201-Intervals(差分约束系统)
- POJ -- 1201--Intervals (差分约束系统)
- POJ 1201 差分约束系统
- poj 1201 Intervals 差分约束系统
- POJ 1201 Candies [差分约束系统]
- POJ 1201 Intervals [差分约束系统]
- POJ 1201 Intervals 差分约束系统
- POJ 1201 Intervals 差分约束系统
- POJ 1201 Intervals 差分约束系统
- POJ-1201 (差分约束系统)
- 【差分约束系统】POJ 1201--Intervals
- [POJ 1201] Intervals 差分约束系统
- POJ 1201 Intervals 差分约束系统
- 差分约束系统 poj
- 【分数规划】[Scoi2014] bzoj3597方伯伯运椰子
- 用C++ 实现(程序自杀)
- URAL 1876. Centipede's Morning (贪心)
- BC#31.1002beautiful number——数位DP/暴力
- Apache与Tomcat7集群(Windows环境)
- poj 1201 (差分约束系统)
- 查看sql server端口
- 第3章1节《MonkeyRunner源码剖析》脚本编写示例: MonkeyRunner API使用示例(原创)
- HDU 1247 Hat’s Words 字典树
- java工程师面试题大全-100%公司笔试题你都能碰到几个
- 离开家乡的人,习惯在外的漂泊,回不去了
- 浅谈 C++ 中的 new/delete 和 new[]/delete[]
- Cocos2d-x 3.x学习笔记:猩先生带你打飞机(六)游戏结束场景
- MFC单文档/多文档程序各类之间的跳转总结