POJ_1201_Intervals

Intervals
Time Limit: 2000MS        Memory Limit: 65536K
Total Submissions: 24303        Accepted: 9237

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

5
3 7 3
8 10 3
6 8 1
1 3 1
10 11 1

Sample Output

6
题意

n个区间,每个区间有三个数
ai ,bi ,ci 表示在[ai,bi]中 至少有ci个点  ci可以在区间内任意取不重复的点
问? 现在要满足所有区间的自身条件,问最少选多少个点

思路:
Si:那也就是说如果我用Si表示区间[0,i]区间内至少有多少个元素的话
差分约束的思想:可以肯定的是s[bi]-s[ai-1]>=ci; 为什么要ai-1,是因为ai也要选进来
但是这远远不够,因为有很多点依然没有相连接起来(也就是从起点可能根本就还没有到终点的路线),
此时,我们再看看Si的定义,也不难写出0<= Si-Si-1 <=1的限制条件,虽然看上去是没有什么意义的条件,
但是如果你也把它构造出一系列的边的话,这样从起点到终点的最短路也就顺理成章的出现了。
s[i]-s[i-1]<=1 && s[i]-s[i-1]>=0

构造:
s[bi]-s[ai-1]>=ci
s[i-1]-s[i]>=-1
s[i]-s[i-1]>=0

建图
求最长路径

看这位大神的思路,理解的

http://www.cnblogs.com/gj-Acit/p/3261721.html


#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
using namespace std;
#define inf 0x3f3f3f3f
struct Node
{
	int v;
	int w;
	int next;
}s[50005*3];
int head[50005];
int dist[50005];
bool vis[50005];
int n,Max,Min,num;
void add_edge(int a,int b,int c)
{
	s[num].v = b;
	s[num].w = c;
	s[num].next = head[a];
	head[a] = num++;
}
void SPFA()
{
	queue<int> Q;
	int i;
	for(i=Min;i<=Max;i++)
	{
		dist[i] = -inf;
	}
	dist[Min] = 0;
	vis[Min] = true;
	Q.push(Min);
	while(!Q.empty())
	{
		int u = Q.front();
		Q.pop();
		vis[u] = false;
		for(i=head[u];i!=-1;i=s[i].next)
		{
			int v = s[i].v;
			int w = s[i].w;
			if(dist[v]<dist[u]+w)
			{
				dist[v] = dist[u] + w;
				if(!vis[v])
				{
					vis[v] = true;	
					Q.push(v);
				}	
			}
		}	
	} 
}
int main()
{
	while(scanf("%d",&n)!=EOF)
	{
		int i,j,a,b,c;
		num = 0;
		Max = -inf;
		Min = inf; 
		memset(head,-1,sizeof(head));
		for(i=0;i<n;i++)
		{
			scanf("%d%d%d",&a,&b,&c);
			Min = min(Min,a);
			Max = max(Max,b+1);
			add_edge(a,b+1,c);
		}
		for(i=Min;i<Max;i++)
		{
			add_edge(i,i+1,0);
			add_edge(i+1,i,-1);	
		}
		SPFA();
		printf("%d\n",dist[Max]);
		
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值