您的位置:首页 > 其它

POJ 1201 Intervals 差分约束

2017-07-10 19:59 387 查看
Intervals

Time Limit: 2000MS Memory Limit: 65536K

Total Submissions: 27159 Accepted: 10425

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,表示[a,b]中至少要选c个不同的元素,问要满足这些限制条件最小要选多少个元素。

不难看出这是一个关于

b-a>=c 然后求满足这些不等式的最小解。

当然是用差分约束啦。

对每个限制条件从a到b连一条权值为c的边,然后跑一遍最长路。

然后兴致勃勃地码一发光荣WA掉。

首先考虑一种情况:

从[1,2]中至少选1个元素,从[2,3]中至少选一个元素,那么从[1,3]中就会至少选2个元素,但实际情况其实只需要2一个元素就够了。

其实[a,b]的元素个数即[0,b]的元素个数-[0,a-1]的元素个数。

所以限制条件可以很容易转化为:

x[b]-x[a-1]>=c 其中x[i]表示[s,i]的元素个数。即从起始到i这个位置的元素个数。

再题中所给的区间序列可能是不连续的,但数与数之间本身就具有一定的限制条件。

对i和i+1,

x]i+1]-x[i]>=0;

x[i+1]-x[i]<=1;

所以将这两个条件转化一下,连边跑最长路就可以了。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<stack>
#include<queue>
using namespace std;

const int N = 500010;
const int INF = 1<<30;

int n;
int s=INF,t=-INF;

struct node{
int pre,v,w;
}edge
;

int num=0;
int head
;

void addedge(int from,int to,int w){
num++;
edge[num].pre=head[from];
edge[num].v=to;
edge[num].w=w;
head[from]=num;
}

bool vis
;
int dis
;
/*stack<int> q;
void SPFA(){
memset(dis,-127,sizeof(dis));
memset(vis,0,sizeof(vis));
q.push(t);dis[t]=0;
while(!q.empty()){
int u=q.top();q.pop();
vis[u]=false;
for(int i=head[u];i;i=edge[i].pre){
int v=edge[i].v;
if(dis[v]<dis[u]+edge[i].w){
dis[v]=dis[u]+edge[i].w;
if(!vis[v]){
q.push(v);
vis[v]=true;
}
}
}
}
}*/

queue <int> q;

void spfa(){
memset(dis,-127,sizeof(dis));
//  for(int i=s;i<=t;i++)
//      dis[i]=-INF;
memset(vis,0,sizeof(vis));
q.push(s),dis[s]=0;
while(!q.empty()){
int u=q.front();q.pop();
vis[u]=false;
for(int i=head[u];i;i=edge[i].pre){
int v=edge[i].v;
if(dis[v]<dis[u]+edge[i].w){
dis[v]=dis[u]+edge[i].w;
if(!vis[v]){
q.push(v);
vis[v]=true;
}
}
}
}
}

int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
addedge(u-1,v,w);
if(t<v) t=v;
if(s>u-1) s=u-1;
}
for(int i=s;i<t;i++){
addedge(i+1,i,-1);
addedge(i,i+1,0);
}
//printf("%d ",t);
//  SPFA();
spfa();//这个要快一点
printf("%d",dis[t]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: