POJ 1201 Intervals (差分约束,最短路)
题意:
有一个集合Z,其元素都是整整数,但是数量未知。现有n个约束,形如 [a,b]=c 表示整数区间[a,b]中有c个元素在Z中出现。问集合Z最小可能含多少个元素?
思路:
对于所给的区间 cnt[b-a]>=k这可以保证了该区间内个数不少于k。但是由于两边都是闭区间,所以要变cnt[b-(a-1)]>=k,表示b到a之间的个数。也就是说,转成式子是b-(a-1)>=k,变换一下为(a-1)-b<=-k,就满足常见的式子b-a<=k啦,可以建边b指向(a-1),权值为-k。
但是还有没有其他的约束条件呢?如果我们只是这样建图,那很多个点都不会有联系的啊,比如[3,7]>=2和 [5,9]>=4,建边为2->7和4>9,完全不搭边啊!肯定还有其他联系,相邻的两个数字之间是否可以有边?可以的,至少可以满足a-(a-1)>=0吧?表示a只能被选与不被选。还有呢?每个点最多只能被选一次吧?则有a-(a-1)<=1。
综合3条式子,可以变形得到:
(1)(a-1)-b<=-k
(2)(a-1)-a<=0
(3)a-(a-1)<=1
都满足了常见的式子。那么可以建边了。这下每两个相邻数字就起码有两条边。注意:求的值是最小的,所以标准形式用<=号。
我们要求的是什么?满足要求的,整个区间所挑的最小个数。从最大数字出发,进行求最短路后,最小的数的那个点通常就会得到一个负权路径和啦,cost[最小]=负值。而cost[最小]取相反数就是答案了。记得开始前要将cost[起点]置为0。大概思路是这样,但是区间是[0,50000],所以0-1时还会出现负数下标,可以将整个区间右移一位变成[1,50001]。
//#include <bits/stdc++.h>
#include <cstdio>
#include <cstring>
#include <map>
#include <iostream>
#include <deque>
#include <vector>
#define INF 0x7f7f7f7f
#define pii pair<int,int>
#define LL unsigned long long
using namespace std;
const int N=;
struct node
{
int from,to,cost;
node(){};
node(int from,int to,int cost):from(from),to(to),cost(cost){};
}edge[N*];
vector<int> vect[N];
int edge_cnt; void add_node(int from,int to,int cost)
{
edge[edge_cnt]=node(from,to,cost);
vect[from].push_back(edge_cnt++);
} bool inq[N];
int cost[N];
int spfa(int small,int big)
{
memset(inq, , sizeof(inq));
memset(cost, 0x7f, sizeof(cost));
cost[big]=;
deque<int> que(,big); while(!que.empty())
{
int x=que.front();que.pop_front();
inq[x]=; for(int i=; i<vect[x].size(); i++)
{
node e=edge[vect[x][i]];
if(cost[e.to]>cost[x]+e.cost)
{
cost[e.to]=cost[x]+e.cost;
if(!inq[e.to])
{
inq[e.to]=;
if(!que.empty() && cost[e.to]<cost[que.front()]) que.push_front(e.to);
else que.push_back(e.to);
}
}
}
}
return -cost[small];
} int main()
{
//freopen("input.txt", "r", stdin);
int n, m, a, b, c;
while(~scanf("%d",&n))
{
edge_cnt=;
memset(edge,,sizeof(edge));
for(int i=; i<N; i++) vect[i].clear();
int small=INF, big=; for(int i=; i<n; i++)
{
scanf("%d%d%d",&a,&b,&c);
add_node(b+,a,-c); //右移了1位 small=min(small, a+);
big=max(big, b+);
}
//每两个点之间的
for(int i=small; i<=big; i++)
{
add_node(i-, i, );
add_node(i, i-, );
}
cout<<spfa(small-, big)<<endl;
}
return ;
}
AC代码
POJ 1201 Intervals (差分约束,最短路)的更多相关文章
- poj 1201 Intervals(差分约束)
题目:http://poj.org/problem?id=1201 题意:给定n组数据,每组有ai,bi,ci,要求在区间[ai,bi]内至少找ci个数, 并使得找的数字组成的数组Z的长度最小. #i ...
- poj 1201 Intervals——差分约束裸题
题目:http://poj.org/problem?id=1201 差分约束裸套路:前缀和 本题可以不把源点向每个点连一条0的边,可以直接把0点作为源点.这样会快许多! 可能是因为 i-1 向 i 都 ...
- POJ 1201 Intervals (差分约束系统)
题意 在区间[0,50000]上有一些整点,并且满足n个约束条件:在区间[ui, vi]上至少有ci个整点,问区间[0, 50000]上至少要有几个整点. 思路 差分约束求最小值.把不等式都转换为&g ...
- POJ 2101 Intervals 差分约束
Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 27746 Accepted: 10687 Description You ...
- poj 1201 Intervals(差分约束)
做的第一道差分约束的题目,思考了一天,终于把差分约束弄懂了O(∩_∩)O哈哈~ 题意(略坑):三元组{ai,bi,ci},表示区间[ai,bi]上至少要有ci个数字相同,其实就是说,在区间[0,500 ...
- POJ 1201 Intervals【差分约束】
传送门:http://poj.org/problem?id=1201 题意: 有n个如下形式的条件:,表示在区间[, ]内至少要选择个整数点.问你满足以上所有条件,最少需要选多少个点? 思路:第一道差 ...
- POJ 1201 Intervals (经典) (差分约束)
<题目链接> 题目大意:给你$n$段区间,$a_i,b_i,c_i$ 表示在 $[a_i,b_i]$ 区间内至少要选择$c_i$个点.现在问你在满足这n个条件的情况下,最少要选多少个点? ...
- poj 1201 Intervals【差分约束+spfa】
设s为前缀和,首先显然的条件是\[ s_{bi}-s_{ai-1}>=c \],然后隐含的是\[ s_i-s_{i-1}>=0 s_i-s_{i-1}<=1 \] 然后根据差分约束, ...
- 【题解】 POJ 1201 Intervals(差分约束)
懒得复制,戳我戳我 Solution: 这道题就是一个板子题 抽象成第\(a\)至第\(b\)间选择数的个数为\(c\),我们就可以用前缀和来表示,这样就可以得到不等式\(s[b]-s[a-1]> ...
- POJ 1201 Intervals(差分约束 区间约束模版)
关于差分约束详情可阅读:http://www.cppblog.com/menjitianya/archive/2015/11/19/212292.html 题意: 给定n个区间[L,R], 每个区间至 ...
随机推荐
- setTimeout延时0毫秒的作用和问题
一 作用 http://www.cnblogs.com/xieex/archive/2008/07/11/1241151.html 经常看到setTimeout延时0ms的javascript代码,感 ...
- C#中反射泛型 CreateInstance
假设1我有个类叫SortClass,类中有个BubbleSort(int[] array)用于给数组进行排序. 假设2我有个类叫SortT<T>,类中有个BubbleSort(T[] ar ...
- BZOJ 1046: [HAOI2007]上升序列 LIS -dp
1046: [HAOI2007]上升序列 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3438 Solved: 1171[Submit][Stat ...
- Linux静态库和动态库
Linux 工具 ❑ GCC: The GNU Compiler Collection, containing the GNU C compiler❑ G++: A C++ compiler, inc ...
- Gradle Goodness: Skip Building Project Dependencies
If we use Gradle in a multi-module project we can define project dependencies between modules. Gradl ...
- 获取手机的UUID
获取手机的UUID 01 连接手机到电脑 02 - 在XCOde中,选择Window->Devices
- lintcode: 最长无重复字符的子串
题目 最长无重复字符的子串给定一个字符串,请找出其中无重复字符的最长子字符串. 例如,在"abcabcbb"中,其无重复字符的最长子字符串是"abc",其长度为 ...
- Linux问题定位工具大放送
我们在程序定位问题时,经常不知所错,但是在linux有很多强大的工具,只要我们合理利用,一定见奇效. 主要会遇到以下问题: 1 mem高 2 cpu高 3 io高 4 网络延迟高 vargrind:h ...
- phpeclipse常用快捷键
phpeclipse常用快捷键
- iOS 安装使用cocoapods
一.什么是CocoaPods 1.为什么需要CocoaPods 在进行iOS开发的时候,总免不了使用第三方的开源库,比如SBJson.AFNetworking.Reachability等等.使用这些库 ...