poj-1201 Intervals(差分约束)

题目链接:

Intervals

Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 24379   Accepted: 9274

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



题意:

给一个区间[ai,bi],这个区间里有ci个相同的元素,问这个集合最少包含多少元素;


思路:

可以得到这样的几个不等式;
c[i]<=dis[b+1]-dis[a];
0<=dis[i+1]-dis[i];
-1<=dis[i]-dis[i+1];

题意是一定要满足这些条件,那么就是找最长路;当然也可以变成>=来建图,求最短路;



AC代码:


//最长路径的代码
//
#include <bits/stdc++.h> #include <iostream> #include <queue> #include <cmath> #include <cstring> #include <algorithm> #include <cstdio> using namespace std; #define Riep(n) for(int i=1;i<=n;i++) #define Riop(n) for(int i=0;i<n;i++) #define Rjep(n) for(int j=1;j<=n;j++) #define Rjop(n) for(int j=0;j<n;j++) #define mst(ss,b) memset(ss,b,sizeof(ss)); typedef long long LL; const LL mod=1e9+7; const double PI=acos(-1.0); const int inf=0x3f3f3f3f; const int N=5e4+5; int n,head[3*N],vis[N],ans[N],cnt,mmin; struct Edge { int to,next,dis; }edge[3*N]; queue<int>qu; void spfa() { mst(vis,0); mst(ans,-inf); ans[mmin]=0; qu.push(mmin); vis[mmin]=1; while(!qu.empty()) { int fr=qu.front(); qu.pop(); for(int i=head[fr];i!=-1;i=edge[i].next) { int x=edge[i].to; if(ans[x]<ans[fr]+edge[i].dis) { ans[x]=ans[fr]+edge[i].dis; if(!vis[x]) { qu.push(x); vis[x]=1; } } } vis[fr]=0; } } void add_edge(int s,int e,int val) { edge[cnt].to=e; edge[cnt].next=head[s]; edge[cnt].dis=val; head[s]=cnt++; } int main() { while(scanf("%d",&n)!=EOF) { int a,b,c,mmax=0; mmin=55000; cnt=0; mst(head,-1); Riep(n) { scanf("%d%d%d",&a,&b,&c); mmax=max(mmax,b); mmin=min(mmin,a); add_edge(a,b+1,c); } Riep(mmax)add_edge(i,i+1,0),add_edge(i+1,i,-1); spfa(); printf("%d\n",ans[mmax+1]); } return 0; }
//最短路径的代码
//#include <bits/stdc++.h>
#include <iostream>
#include <queue>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
#define Riep(n) for(int i=1;i<=n;i++)
#define Riop(n) for(int i=0;i<n;i++)
#define Rjep(n) for(int j=1;j<=n;j++)
#define Rjop(n) for(int j=0;j<n;j++)
#define mst(ss,b) memset(ss,b,sizeof(ss));
typedef long long LL;
const LL mod=1e9+7;
const double PI=acos(-1.0);
const int inf=0x3f3f3f3f;
const int N=5e4+5;
int n,head[3*N],vis[N],ans[N],cnt,mmin,mmax;
struct Edge
{
    int to,next,dis;
}edge[3*N];
queue<int>qu;
void spfa()
{
    mst(vis,0);
    mst(ans,inf);
    ans[mmax]=0;
    qu.push(mmax);
    vis[mmax]=1;
    while(!qu.empty())
    {
        int fr=qu.front();
        qu.pop();
        for(int i=head[fr];i!=-1;i=edge[i].next)
        {
            int x=edge[i].to;
            if(ans[x]>ans[fr]+edge[i].dis)
            {
                ans[x]=ans[fr]+edge[i].dis;
                if(!vis[x])
                {
                    qu.push(x);
                    vis[x]=1;
                }
            }
        }
        vis[fr]=0;
    }
}
void add_edge(int s,int e,int val)
{
    edge[cnt].to=e;
    edge[cnt].next=head[s];
    edge[cnt].dis=val;
    head[s]=cnt++;
}
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        int a,b,c;
        mmax=0;
        mmin=55000;
        cnt=0;
        mst(head,-1);
        Riep(n)
        {
            scanf("%d%d%d",&a,&b,&c);
            mmax=max(mmax,b+1);
            mmin=min(mmin,a);
            add_edge(b+1,a,-c);
        }
        Riep(mmax)add_edge(i,i+1,1),add_edge(i+1,i,0);
        spfa();
        printf("%d\n",-ans[mmin]);
    }
    return 0;
}

 

posted @ 2016-05-09 23:25  LittlePointer  阅读(426)  评论(0编辑  收藏  举报