您的位置:首页 > 其它

poj1201Intervals——差分约束系统

2016-02-29 21:24 253 查看
poj1201Intervals:http://poj.org/problem?id=1201

Intervals

Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 24036 Accepted: 9125
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(闭区间),表示集合Z在这个区间内有ci个相同元素,问这个集合Z里至少有多少个元素。

思路:差分约束的变形. 根据题意可以得到bi-ai>=ci,这样就可以建一条ai到bi,权值为ci的边。然而只有这些边并不能把那些离散的点连接起来(不连接起来可能无法到终点)。再挖掘题目,由0 <= ai <= bi <= 50000 and 1 <= ci <= bi - ai+1.可以得到i+1-i>= 0,i-(i+1) >= -1;把这些边都加上,求出最长路径就可以了。

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <set>
#include <queue>

using namespace std;
#define INF 1000000007
#define maxn 50005

struct Edge
{
int v;
int w;
int next;
} edge[maxn * 3];

int head[maxn],d[maxn],vis[maxn],n = 0,maxx,minn;
void Add(int u,int v,int w)
{
edge
.v = v;
edge
.w = w;
edge
.next = head[u];
head[u] = n ++;
}

void spfa()
{
for(int i = minn; i <= maxx; i++)
d[i] = -INF;
queue<int>q;
q.push(minn);
d[minn] = 0;
while(!q.empty())
{
int v = q.front();
q.pop();
vis[v] = 0;
for(int i = head[v]; i != -1; i = edge[i].next)
if(d[edge[i].v] < d[v] + edge[i].w) // 求最长路径
{
d[edge[i].v] = d[v] + edge[i].w;
if(!vis[edge[i].v])
{
vis[edge[i].v] = 1;
q.push(edge[i].v);
}
}
}
}
int main()
{
int t,u,v,w;
maxx = -INF;
minn = INF;
memset(head,-1,sizeof(head));
memset(vis,0,sizeof(vis));
scanf("%d",&t);
while(t --)
{
scanf("%d%d%d",&u,&v,&w);
Add(u,v+1,w);
minn = min(minn,u);
maxx = max(maxx,v+1);
}
for(int i = minn; i < maxx; i++)
{
Add(i,i+1,0);
Add(i+1,i,-1);
}
spfa();
printf("%d\n",d[maxx]);
return 0;
}


差分约束系统:http://www.cnblogs.com/void/archive/2011/08/26/2153928.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: