zoukankan      html  css  js  c++  java
  • hdoj--1384--Intervals(差分约束)

    Intervals

    Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 3559    Accepted Submission(s): 1303


    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
     

    Author
    1384
     

    Recommend
    Eddy   |   We have carefully selected several similar problems for you:  1529 1531 1548 1534 1317 

    题意:给出n个区间的左右端点,和这个区间内至少存在的在集合s中的点的个数,让你求集合s中最少有多少个点
    题解:重在找到差分约束的约束条件,将约束条件转化为xj-xi<=k的形式,然后建立一条从i到j权值为k的边;
    设maxl为区间的左端点,maxr为区间的右端点,S[i] 表示集合Z里面的元素在区间[0, i ]的个数,Maxl,Maxr分别表示所有区间里面的最左端和最右端,dist[]数组存储源点到某点的最短路。则由题意得限制条件
    一 S[right] -  S[left-1] >= least 即[left, right]区间个数不小于least,转换得S[left-1] - S[right] <= least;
    二 0 <= S[i] - S[i-1] <= 1转换得 S[i-1] - S[i] <= 0 && S[i] - S[i-1] <= 1。
    第二个条件题中并没有给出,需要自己推导,因为仅仅靠题中的条件无法构建一个连通图,也就无法求最短路,因为s[i]表示的是集合Z里面的元素在区间[0, i ]的个数所以s[i]至多比s[i-1]大一也可能相等
    然后根据限制条件建图
    转化问题:题目需要求的是S[Maxr] - S[Maxl-1] >= ans 即S[Maxl-1] - S[Maxr] <= -ans。 若以Maxr为源点 ,而-ans就为Maxr到Maxl-1的最短路径的相反数,即-dist[Maxl-1]。

    #include<stdio.h>
    #include<string.h>
    #include<queue>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define INF 0x3f3f3f
    int head[100100],vis[1000100],n,cnt;
    int dis[100100];
    int l,r;
    struct node
    {
    	int u,v,val;
    	int next;
    }edge[1001000];
    void init()
    {
    	cnt=0;
    	memset(head,-1,sizeof(head));
    	l=INF;
    	r=-1;
    }
    void add(int u,int v,int val)
    {
    	node E={u,v,val,head[u]};
    	edge[cnt]=E;
    	head[u]=cnt++;
    }
    void getmap()
    {
    	int a,b,c;
    	for(int i=0;i<n;i++)
    	{
    		cin>>a>>b>>c;
    		l=min(a,l);
    		r=max(r,b);
    		add(b,a-1,-c);
    	}
    	for(int i=l;i<=r;i++)
    	{
    		add(i,i-1,0);
    		add(i-1,i,1);
    	}
    }
    void SPFA()
    {
    	for(int i=l-1;i<=r;i++)
    	dis[i]=i==r?0:INF; 
    	memset(vis,0,sizeof(vis));
    	queue<int>q;
    	q.push(r);
    	vis[r]=1;
    	while(!q.empty())
    	{
    		int u=q.front();
    		q.pop();
    		vis[u]=0;
    		for(int i=head[u];i!=-1;i=edge[i].next)
    		{
    			node E=edge[i];
    			if(dis[E.v]>dis[E.u]+edge[i].val)
    			{
    				dis[E.v]=dis[E.u]+edge[i].val;
    				if(!vis[E.v])
    				{
    					vis[E.v]=1;
    					q.push(E.v);
    				}
    			}
    		}
    	}
    	cout<<-dis[l-1]<<endl;
    }
    int main()
    {
    	while(scanf("%d",&n)!=EOF)
    	{
    		init();
    		getmap();
    		SPFA();
    	}
    	return 0;
    }


  • 相关阅读:
    基于Metaweblog API 接口一键发布到国内外主流博客平台
    uva144 Student Grants
    Uva 10452
    Uva 439 Knight Moves
    Uva 352 The Seasonal War
    switch语句
    java——基础知识
    我的lua学习2
    codeforces 431 D. Random Task 组合数学
    codeforces 285 D. Permutation Sum 状压 dfs打表
  • 原文地址:https://www.cnblogs.com/playboy307/p/5273549.html
Copyright © 2011-2022 走看看