差分约束学习(一)POJ1201
2015-12-03 20:29
323 查看
在vj上找到的差分约束专题:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=50942#overview
一开始好像很快就明白差分约束这是要建立边,然后通过求最短路的方法求解,但真到做的时候发现建立边的过程中真是各种出错,感觉还是要通过做一些题目才能不断总结、理解。
POJ1201:
Intervals
Description
You are given n closed, integer intervals [ai, bi] and n integers c1, ..., cn.
Write a program that:
reads the number of intervals, their end points and integers c1, ..., cn from the standard input,
computes the minimal size of a set Z of integers which has at least ci common elements with interval [ai, bi], for each i=1,2,...,n,
writes the answer to the standard output.
Input
The first line of the input contains an integer n (1 <= n <= 50000) -- the number of intervals. The following n lines describe the intervals. The (i+1)-th line of the input contains three integers ai, bi and ci separated by single spaces and such that 0 <=
ai <= bi <= 50000 and 1 <= ci <= bi - ai+1.
Output
The output contains exactly one integer equal to the minimal size of set Z sharing at least ci elements with interval [ai, bi], for each i=1,2,...,n.
Sample Input
Sample Output
题意是给出了一堆区间[a,b],每个区间和整数集Z都至少有c个相同元素。问整个区间内和整数集Z至少有多少个相同元素。
用val[x]表示[0,x]这个区间和整数集Z相同的元素个数。这样区间[a,b]与整数集Z相同的个数就可以表示为val[b]-val[a-1]。每一个条件就可以化为val[b]-val[a-1]>=c。
然后求的就是val[max]-val[min-1]>=x,x即为所求。
然后就是通过建立边,求图的最短路径。注意差分约束里面难就难在发觉隐含条件建立边,这里面的隐含条件在于1>=val[a+1]-val[a]>=0,所以能够得到两个边val[a+1]-val[a]>=0 与 val[a]-val[a+1]>=-1。
代码:
一开始好像很快就明白差分约束这是要建立边,然后通过求最短路的方法求解,但真到做的时候发现建立边的过程中真是各种出错,感觉还是要通过做一些题目才能不断总结、理解。
POJ1201:
Intervals
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 23755 | Accepted: 8994 |
You are given n closed, integer intervals [ai, bi] and n integers c1, ..., cn.
Write a program that:
reads the number of intervals, their end points and integers c1, ..., cn from the standard input,
computes the minimal size of a set Z of integers which has at least ci common elements with interval [ai, bi], for each i=1,2,...,n,
writes the answer to the standard output.
Input
The first line of the input contains an integer n (1 <= n <= 50000) -- the number of intervals. The following n lines describe the intervals. The (i+1)-th line of the input contains three integers ai, bi and ci separated by single spaces and such that 0 <=
ai <= bi <= 50000 and 1 <= ci <= bi - ai+1.
Output
The output contains exactly one integer equal to the minimal size of set Z sharing at least ci elements with interval [ai, bi], for each i=1,2,...,n.
Sample Input
5 3 7 3 8 10 3 6 8 1 1 3 1 10 11 1
Sample Output
6
题意是给出了一堆区间[a,b],每个区间和整数集Z都至少有c个相同元素。问整个区间内和整数集Z至少有多少个相同元素。
用val[x]表示[0,x]这个区间和整数集Z相同的元素个数。这样区间[a,b]与整数集Z相同的个数就可以表示为val[b]-val[a-1]。每一个条件就可以化为val[b]-val[a-1]>=c。
然后求的就是val[max]-val[min-1]>=x,x即为所求。
然后就是通过建立边,求图的最短路径。注意差分约束里面难就难在发觉隐含条件建立边,这里面的隐含条件在于1>=val[a+1]-val[a]>=0,所以能够得到两个边val[a+1]-val[a]>=0 与 val[a]-val[a+1]>=-1。
代码:
#include <iostream> #include <algorithm> #include <cmath> #include <vector> #include <string> #include <cstring> #include <queue> #pragma warning(disable:4996) using namespace std; #define INF 1000000007 #define MAXN 50005 struct EDGE { int v; int w; int next; }edge[3*MAXN]; int head[MAXN], d[MAXN], vis[MAXN], N, n, Max, Min; void AddEdge(int u, int v, int w) { edge .v = v; edge .w = w; edge .next = head[u]; head[u] = N++; } void SPFA() { int x, i, e; for (i = Min; i <= Max; i++) d[i] = -INF; d[Min] = 0; queue<int>q; q.push(Min); while (!q.empty()) { x = q.front(); q.pop(); vis[x] = 0; for (int e = head[x]; e != -1; e = edge[e].next) { if (d[edge[e].v] < d[x] + edge[e].w) { d[edge[e].v] = d[x] + edge[e].w; if (!vis[edge[e].v]) { q.push(edge[e].v); vis[edge[e].v] = 1; } } } } } int main() { //freopen("i.txt","r",stdin); //freopen("o.txt","w",stdout); int i; int u, v, w; while (scanf("%d", &n) != EOF) { N = 0; memset(head, -1, sizeof(head)); memset(vis, 0, sizeof(vis)); memset(edge, 0, sizeof(edge)); Min = INF; Max = -INF; for (i = 0; i < n; i++) { scanf("%d%d%d", &u, &v, &w); AddEdge(u, v + 1, w); Min = min(Min, u); Max = max(Max, v + 1); } for (i = Min; i < Max; i++) { AddEdge(i, i + 1, 0); AddEdge(i + 1, i, -1); } SPFA(); printf("%d\n", d[Max]); } //system("pause"); return 0; }
相关文章推荐
- Android 实现调用照相机和选取本地照片功能
- 有穷自动机
- android 的Drawable
- Hint:Parameter 'in' is declared but never used in 'query_student'
- 迭代器
- 随笔1
- python write出现 Non-character array cannot be interpreted as character buffer.
- windows xp 和 ubuntu双系统出现grub,如何设置直接进入双系统选择界面
- Object-C,NSSet,不可变集合
- Object-C,NSSet,不可变集合
- Object-C,NSSet,不可变集合
- HDOJ 5499 SDOI 【结构体排序】
- 详解python linecache模块读取文件的方法
- hdoj 反素数 2521 (打表&暴力)
- XMPP
- Android图片之三级缓存(着重讲内存缓存)
- LeetCode 14 : Longest Common Prefix (Java)
- Python环境下新模块的安装(httplib2)
- [leetcode] 103. Binary Tree Zigzag Level Order Traversal
- ZOJ - 2972 Hurdles of 110m