zoukankan      html  css  js  c++  java
  • POJ 1201 Intervals(图论-差分约束)

    Intervals
    Time Limit: 2000MS   Memory Limit: 65536K
    Total Submissions: 20779   Accepted: 7863

    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

    Source


    题目大意:

    n行。每行a,b,c,表示在区间a,b内要找c个数,问你总共至少要找多少个数?

    解题思路:

    差分约束系统。
    在本题中。假设[a,b]中要找c个元素。那么:s[b]-s[a-1]>=c。我们能够推得:s[a-1] - s[b] <= -c

    同一时候。因为每个值上最多仅仅能含有一个元素。那么:s[i] - s[i-1]<=1 ,又因为s[i] - s[i-1]>=0 推得:s[i-1] - s[i] <=0

    这样:我们有了三个约束不等式:
    s[a-1] - s[b] <= -c
    s[i] - s[i-1]<=1 
    s[i-1] - s[i] <=0


    于是:假设起点为from,终点为to。我们仅仅要求出:s[to] -s[from-1] >= M就能够了,

    因此求出 s[from-1]-s[to]<=-M,即求to 到 from-1 的最短路径,

    注意:因为i<0,所以i-1可能小于0,因此所有向右平移1位。


    解题代码:

    #include <iostream>
    #include <queue>
    #include <cstdio>
    using namespace std;
    
    const int maxn=50000;
    const int inf=0x3f3f3f3f;
    
    struct edge{
        int u,v,w,next;
    }e[maxn*10];
    
    int head[maxn*2+10],dist[maxn*2+10],cnt;
    int n,from,to;
    
    void initial(){
        cnt=0;
        from=inf,to=0;
        for(int i=0;i<=maxn;i++) head[i]=-1;
    }
    
    void adde(int u,int v,int w){
        u++;v++;
        e[cnt].u=u,e[cnt].v=v,e[cnt].w=w,e[cnt].next=head[u],head[u]=cnt++;
    }
    
    void input(){
        int u,v,w;
        //[v]-[u-1]>=w [u-1]-[v]<=-w
        for(int i=0;i<n;i++){
            scanf("%d%d%d",&u,&v,&w);
            adde(v,u-1,-w);
            if(u<from) from=u;
            if(v>to) to=v;
        }
        //0<=[i]-[i-1]<=1
        for(int i=from;i<=to;i++){
            adde(i-1,i,1);
            adde(i,i-1,0);
        }
    }
    
    bool spfa(int from){
        int s=from,num[maxn];
        bool visited[maxn];
        for(int i=0;i<=maxn;i++){
            num[i]=0;
            dist[i]=inf;
            visited[i]=false;
        }
        queue <int> q;
        q.push(s);
        visited[s]=true;
        dist[s]=0;
        while(!q.empty()){
            s=q.front();
            q.pop();
            for(int i=head[s];i!=-1;i=e[i].next){
                int d=e[i].v;
                if(dist[d]>dist[s]+e[i].w){
                    dist[d]=dist[s]+e[i].w;
                    if(!visited[d]){
                        visited[d]=true;
                        q.push(d);
                        num[d]++;
                        if(num[d]>n) return false;
                    }
                }
            }
            visited[s]=false;
        }
        return true;
    }
    
    void solve(){
        //get [to]-[from-1]>=M; [from-1]-[to]<=-M
        spfa(to+1);
        cout<<-dist[from]<<endl;
    }
    
    int main(){
        while(scanf("%d",&n)!=EOF){
            initial();
            input();
            solve();
        }
        return 0;
    }
    



  • 相关阅读:
    什么是css权重
    html5 canvas画五角星(美国队长)
    从输入URL到页面加载发生了什么
    javascript之事件委托(转)
    javascript之常用排序算法
    javascript之闭包
    javascript二维数组的删除
    javascript之apply()、call()
    div+css两列布局与三列布局
    css处理水平居中问题(淘宝双飞翼布局)
  • 原文地址:https://www.cnblogs.com/blfshiye/p/5230493.html
Copyright © 2011-2022 走看看