码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 1201 Intervals 差分约束

时间:2015-07-15 21:05:03      阅读:103      评论:0      收藏:0      [点我收藏+]

标签:差分约束

链接:http://poj.org/problem?id=1201

Intervals
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 23123   Accepted: 8728

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

点只存在于区间内。

然后问负无穷到正无穷最多有多少点。

做法:

我们从最左边到最右边。

区间内最少有c个点,说明点(a-1)到b点 最少会增加c个点。

也就是说  b-(a-1)>=c  转换下   (a-1)-b<=-c 就是差分约束的公式了。

然后就是建边 建一条权值为-c   的b到(a-1)的边就行了。

然后取最小的坐标x,取最大的坐标d。

因为求最大值  所以得公式 d-(x-1)>=?

加个负号, (x-1)-d<=-?   ,所以最后最短路 计算 d点到(x-1)的最短距离,然后取负就是答案了。


但是这样条件还不够。

还有关键的是相邻点之间的建边,设相邻两点  (i) 和(i+1)   

走到(i+1)数到的点数  肯定是比左边的(i)要大的 , 所以 (i+1)-(i)>=0  加个负号, (i)-(i+1)<=0

而从(i)走到(i+1)最多只增加了一个点,所以(i+1)-(i)<=1 ,   

所以还要建这些边,才能跑出最后的答案。


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <malloc.h>
#include <ctype.h>
#include <math.h>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
#include <stack>
#include <queue>
#include <vector>
#include <deque>
#include <set>
#include <map>
 
#define VM 60000
#define EM 160005
#define inf 0x7f7f7f7f
int head[VM],ep;
struct edge
{
    int v,w,next;
}e[EM];

void addedge(int cu,int cv,int cw)
{
    ep ++;
    e[ep].v = cv;
    e[ep].w = cw;
    e[ep].next = head[cu];
    head[cu] = ep;
}

int spfa (int n,int sta,int ee)
{
    int vis[VM],stack[VM],dis[VM],vn[VM];
    memset(vis,0,sizeof(vis));
	memset(dis,inf,sizeof dis); 
	//for(int i=1;i<=n;i++)
	//dis[i]=-inf;
	memset(vn,0,sizeof vn);
	vn[sta]=1;
    dis[sta] = 0;
    vis[sta] = 1;
    int top = 1;
    stack[0] = sta;
    while (top)
    { 
        int u = stack[--top];
		if(vn[u]>n)
			return -inf;
        vis[u] = 0;
        for (int i = head[u];i != -1;i = e[i].next)
        {
            int v = e[i].v;
            if (dis[v] > dis[u] + e[i].w)
            {
                dis[v] = dis[u] + e[i].w;
                if (!vis[v])
                {
                    vis[v] = 1;
					vn[v]++;
                    stack[top++] = v;
                }
            }
        }
    } 
    return dis[ee];
}
int main ()
{ 
    int n,m,v1,v2,cost;
	int ml,md;
	while(scanf("%d",&n)!=EOF)
	{
		ep = 0;
		memset (head,-1,sizeof(head));
		


		int minn=999999;
		int maxx=0;
		for(int i=0;i<n;i++)
		{
			int u,v,lim;
			scanf("%d%d%d",&u,&v,&lim); //v-u<=lim
			u++;
			v++;

			maxx=max(maxx,v);
			minn=min(minn,u);
			addedge(v,u-1,-lim);//   v-(u-1)>=lim   (u-v)<=lim
		}
		
		//for(int i=0;i<50001;i++)
		for(int i=minn-1;i<maxx;i++)
		{ 
			addedge(i+1,i,0);//(i)-(i+1)《=0   后面的点数大 
			addedge(i,i+1,1);//(i+1)-(i)《=1   i+1 最多放一个 
		}

		/*
		for(int i=1;i<n;i++)
		{
			addedge(i+1,i,0);//dian(i)- dian(i+1)<=0
		}*/
		int ans=spfa(maxx-minn+2,maxx,minn-1);
		if(ans==-inf)
			puts("-1");//负环 有矛盾条件
		else if(ans==inf)//两者可以无线远
			puts("-2");
		else
			printf("%d\n",-ans);
	}
	return 0;
}





版权声明:本文为博主原创文章,未经博主允许不得转载。

POJ 1201 Intervals 差分约束

标签:差分约束

原文地址:http://blog.csdn.net/u013532224/article/details/46897989

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!