Intervals

Intervals

Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 52 Accepted Submission(s): 32
 
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
 
/*
题意:给n个条件 ai bi ci 表示在[ai,bi]最少取ci个数,问你最少取多少点,才能满足这些条件

初步思路:差分约束问题,差分约束问题,实际上就是利用图论的知识计算不等式,每个不等式建立一条边,然后利用最短路
    跑一下
*/
#include<bits/stdc++.h>
using namespace std;
int u,v,w,n;
/*****************************************************spaf模板*****************************************************/
template<int N,int M>
struct Graph
{
    int top;
    struct Vertex{
        int head;
    }V[N];
    struct Edge{
        int v,next;
        int w;
    }E[M];
    void init(){
        memset(V,-1,sizeof(V));
        top = 0;
    }
    void add_edge(int u,int v,int w){
        E[top].v = v;
        E[top].w = w;
        E[top].next = V[u].head;
        V[u].head = top++;
    }
};

Graph<50005,150005> g;

const int N = 5e4 + 5;

int d[N];//从某一点到i的最短路
int inqCnt[N];

bool inq[N];//标记走过的点

bool spfa(int s,int n)
{
    memset(inqCnt,0,sizeof(inqCnt));
    memset(inq,false,sizeof(inq));
    memset(d,-63,sizeof(d));
    queue<int> Q;
    Q.push(s);//将起点装进队列中
    inq[s] = true;
    d[s] = 0;
    while(!Q.empty())
    {
        int u = Q.front();
        for(int i=g.V[u].head;~i;i=g.E[i].next)//遍历所有这个点相邻的点
        {
            int v = g.E[i].v;
            int w = g.E[i].w;
            if(d[u]+w>d[v])//进行放缩
            {
                d[v] = d[u] + w;
                if(!inq[v])//如果这个点没有遍历过
                {
                    Q.push(v);
                    inq[v] = true;
                    if(++inqCnt[v] > n)
                        return true;
                }
            }
        }
        Q.pop();//将这个点出栈
        inq[u] = false;
    }
    return false;
}
/*****************************************************spaf模板*****************************************************/
int main(){
    // freopen("in.txt","r",stdin);
    while(scanf("%d",&n)!=EOF){
        g.init();
        int L=50005,R=0;  
        for(int i=0;i<n;i++){  
            scanf("%d%d%d",&u,&v,&w);
            ++u,++v;
            //找出左右两个边界
            L=min(L,u);  
            R=max(R,v);
            g.add_edge(u-1,v,w);
        }  
        for(int i=L;i<=R;i++)  {  
            g.add_edge(i-1,i,0);  
            g.add_edge(i,i-1,-1);  
        }  
        spfa(L-1,R-L+2);  
        printf("%d
",d[R]);  
        
    }
    return 0;
}
原文地址:https://www.cnblogs.com/wuwangchuxin0924/p/6442799.html