差分约束系统——POJ 1201

对应POJ题目:点击打开链接


Intervals
Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u
Submit  Status  Practice  POJ 1201

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个区间,每个区间[a, b] 和c表示此区间内至少有c个元素是属于集合,确定该集合最少有多少个元素。

思路:差分约束系统;设0~i中有S[i]个元素属于集合,那例子就可以表示为:

S[7] - S[2]  >= 3

S[10] - S[7]  >= 3

S[8] - S[5]  >= 1

S[3] - S[0]  >= 1

S[11] - S[9]  >= 1

差分约束系统——POJ 1201_第1张图片

则此题的答案就是求S[max] - S[min-1],即是以最大元素为起点,最小元素为终点的最长路。。。

  此外还有一些隐含条件:0 <= S[i+1] - S[i] <=1


#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<algorithm>
#include<cstring>
#include<string>
#include<iostream>
using namespace std;
const int MAXN=160000+10;
const int INF=1<<30;
int n,m,mm,num;
int dis[50020];
int head[50020];
int vis[50020];
int minn=INF,maxn=0;

struct edge
{
	int v,w,next;
}E[MAXN];

void buildmap(int u, int v, int w)
{
	E[num].v=v;
	E[num].w=w;
	E[num].next=head[u];
	head[u]=num++;
}

void spfa()
{
	memset(vis, 0, sizeof(vis));
	for(int i=minn; i<=maxn; i++) dis[i]=-INF;
	dis[maxn]=0;
	vis[maxn]=1;
	queue<int>q;
	q.push(maxn);
	while(!q.empty())
	{
		int u=q.front();
		q.pop();
		vis[u]=0;
		for(int i=head[u]; i!=-1; i=E[i].next){
			int v=E[i].v;
			if(dis[u]+E[i].w > dis[v]){
				dis[v] = dis[u]+E[i].w;
				if(!vis[v]){
					vis[v]=1; 
					q.push(v);
				}
			}
		}
	}
}

int main()
{
	//freopen("in.txt","r",stdin);
	while(scanf("%d", &n)==1)
	{
		memset(head, -1, sizeof(head));
		num=0;
		int i,j;
		minn=INF, maxn=0;
		for(i=0; i<n; i++){
			int u,v,w;
			scanf("%d%d%d", &v,&u,&w);
			u++;
			if(v<minn) minn=v;
			if(u>maxn) maxn=u;
			buildmap(u,v,w);
		}
		for(i=minn; i<maxn; i++){
			buildmap(i+1,i,0);
			buildmap(i,i+1,-1);
		}
		spfa();
		printf("%d\n", dis[minn]);
	}
}






你可能感兴趣的:(差分约束系统——POJ 1201)