HDU1384 Intervals (差分约束)

HDU1384 Intervals

Problem 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 endpoints 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 <= 50 000) - 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 <= 50 000 and 1 <= ci <= bi - ai + 1.
Process to the end of file.

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

题解

题意

已知一些区间,且要求区间内的点的值要多于给出的要求,求最少需要多少点。

思路

差分约束的模板题目。实际上差分约束的求解是利用了建图过程,将不等式的约束条件转化为权值,利用求最小路过程中的松弛条件进行了更新。最后将不等式求极值的问题转化为最长路、最短路问题。

代码

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 0x3f3f3f3f;

#define REP(i,n) for(int i=0;i<(n);i++)

const int MAXN = 1e5+10;
int dis[MAXN],first[MAXN],vis[MAXN];
int tot,n,S,T,u,v,w;

struct Node{
	int v;
	int w;
	int nxt;
}edge[MAXN*10];

void addedge(int u,int v,int w){
	edge[tot].v = v;
	edge[tot].w = w;
	edge[tot].nxt = first[u];
	first[u] = tot++;
}

void SPFA(int s){
	queue<int>q1;
	memset(dis,-INF,sizeof(dis));
	memset(vis,0,sizeof(vis));
	q1.push(s);
	dis[s] = 0;
	while(q1.empty()==0){
		int u = q1.front();
		q1.pop();
		vis[u]=0;
		for(int i=first[u];~i;i=edge[i].nxt){
			Node cur = edge[i];
			if(dis[cur.v]<dis[u]+edge[i].w){
				dis[cur.v]=dis[u]+edge[i].w;
				if(!vis[cur.v]){
					vis[cur.v]=1;
					q1.push(cur.v);
				}
			}
		}
	}
}

int main(){
	while(~scanf("%d",&n)){
		tot=1, S=INF,T=-INF;
        memset(first,-1,sizeof first);
        for(int i=1;i<=n;i++){
            scanf("%d%d%d",&u,&v,&w);
            S=min(S,u-1),T=max(T,v);
            addedge(u-1,v,w);
        }
        for(int i=S;i<T;i++){
            addedge(i,i+1,0);
            addedge(i+1,i,-1);
        }
        SPFA(S);
        printf("%d\n",dis[T]);
    }
	return 0;
}
posted @ 2018-08-08 20:55  caomp  阅读(182)  评论(0)    收藏  举报