题意:

  有一个集合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 (差分约束,最短路)的更多相关文章

  1. poj 1201 Intervals(差分约束)

    题目:http://poj.org/problem?id=1201 题意:给定n组数据,每组有ai,bi,ci,要求在区间[ai,bi]内至少找ci个数, 并使得找的数字组成的数组Z的长度最小. #i ...

  2. poj 1201 Intervals——差分约束裸题

    题目:http://poj.org/problem?id=1201 差分约束裸套路:前缀和 本题可以不把源点向每个点连一条0的边,可以直接把0点作为源点.这样会快许多! 可能是因为 i-1 向 i 都 ...

  3. POJ 1201 Intervals (差分约束系统)

    题意 在区间[0,50000]上有一些整点,并且满足n个约束条件:在区间[ui, vi]上至少有ci个整点,问区间[0, 50000]上至少要有几个整点. 思路 差分约束求最小值.把不等式都转换为&g ...

  4. POJ 2101 Intervals 差分约束

    Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 27746   Accepted: 10687 Description You ...

  5. poj 1201 Intervals(差分约束)

    做的第一道差分约束的题目,思考了一天,终于把差分约束弄懂了O(∩_∩)O哈哈~ 题意(略坑):三元组{ai,bi,ci},表示区间[ai,bi]上至少要有ci个数字相同,其实就是说,在区间[0,500 ...

  6. POJ 1201 Intervals【差分约束】

    传送门:http://poj.org/problem?id=1201 题意: 有n个如下形式的条件:,表示在区间[, ]内至少要选择个整数点.问你满足以上所有条件,最少需要选多少个点? 思路:第一道差 ...

  7. POJ 1201 Intervals (经典) (差分约束)

    <题目链接> 题目大意:给你$n$段区间,$a_i,b_i,c_i$ 表示在 $[a_i,b_i]$ 区间内至少要选择$c_i$个点.现在问你在满足这n个条件的情况下,最少要选多少个点? ...

  8. poj 1201 Intervals【差分约束+spfa】

    设s为前缀和,首先显然的条件是\[ s_{bi}-s_{ai-1}>=c \],然后隐含的是\[ s_i-s_{i-1}>=0 s_i-s_{i-1}<=1 \] 然后根据差分约束, ...

  9. 【题解】 POJ 1201 Intervals(差分约束)

    懒得复制,戳我戳我 Solution: 这道题就是一个板子题 抽象成第\(a\)至第\(b\)间选择数的个数为\(c\),我们就可以用前缀和来表示,这样就可以得到不等式\(s[b]-s[a-1]> ...

  10. POJ 1201 Intervals(差分约束 区间约束模版)

    关于差分约束详情可阅读:http://www.cppblog.com/menjitianya/archive/2015/11/19/212292.html 题意: 给定n个区间[L,R], 每个区间至 ...

随机推荐

  1. login shell 和 non-login shell 的区别

    介绍之前先思考一个问题:有时我们通过su命令切换用户后,却发现并没有进入该用户的shell环境.这是为什么? login shell:取得bash时需要完整的登录流程.就是说通过输入账号和密码登录系统 ...

  2. DevExpress Form那些事儿

    1:设置子窗体依附父窗体 首先将父窗体的属性中  IsMdiContainer 设置为 True   , 就是将窗体设置为 MDI窗体.子窗体和父窗体都是继承自RibbonForm的. 代码如下 : ...

  3. editplus的各式插件

    C/C++, Java, JSP, C#, .NET, SQL, Pascal, Python, Assembly, Basic files http://www.editplus.com/javac ...

  4. ExtJs之Panel基本布局

    <!DOCTYPE html> <html> <head> <title>ExtJs</title> <meta http-equiv ...

  5. phpstorm安装,破解及使用

    小黑小波比.下载安装phpstorm以及破解 PHPStorm下XDebug配置 phpstorm官方下载地址 PhpStorm 注册码 2.在这输入用户名和注册码,点击OK 破解成功! phpsto ...

  6. 多线程包:java.util.concurrent,

    Java1.5提供了一个非常高效实用的多线程包:java.util.concurrent,

  7. vmware通过vmnet8共享本地网络

    转载于:http://zhaolongchn.blog.163.com/blog/static/19065850420122595117886/ 1,首先将真实电脑的虚拟网卡VMnet8启用 2,然后 ...

  8. web appbuilder 改变样式和添加自定义widget

    一.改变样式 要实现的效果是添加cyan样式 1.将FoldableTheme/style下的cyan copy到TabTheme下的同一目录下: 2.打开TabTheme下的manifest,cop ...

  9. 使用RedisTemplate的操作类访问Redis(转)

    深入理解Spring Redis的使用 (三).使用RedisTemplate的操作类访问Redis 事务需要开启enableTransactionSupport,然后使用@transactional ...

  10. Linux远程文件传输

    linux系统中,难免会遇到一些要将某文件通过网络传送给其他主机的情况,而恰好两台主机 都是linux系统的时候,我们就可以直接使用scp命令来传输文件到另一台主机了. scp命令用于在网络中安全的传 ...