Intervals poj1201

Intervals
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 25784   Accepted: 9870

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

這個題就是讓你找出一個總的序列s包括如:

3 4 5 6 7 的序列中s中至少有三個

8-10中s至少有3個

6-8中s至少有1個

1-3中s至少有1個

10 11中至少有1個

問你s最少有多少個能滿足上述的情況。


這題我們就用差分約束的方法,可以令題目更簡單

這裏我們用d數組來存(意義就是如:d[6]代表0-5中s最少包含幾個)

那麼條件就會滿足

0<=d[i+1]-d[i]<=1;

d[v+1]-d[u]>=dist;

我們求得是滿足所有的條件那麼就要找“最大路徑”也就是所有的條件都要“<=”

我們將上面的公式變形就會得到:

d[i+1]-d[i]<=1;

d[i]-d[i+1]<=0;

d[u]-d[v+1]<=-dist;

然後我們就可以用SPFA算法求得了。

代碼如下:

#include <cstring>
#include <cstdio>
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;

const int N = 50010;
const int INF = 0x3f3f3f3f;
struct node
{
    int dist, to, next;
}E[3*N];
int head[N], d[N], n, tot;
bool vis[N];

void AddEdge(int u, int v, int dist)
{
    E[tot].to = v;
    E[tot].dist = dist;
    E[tot].next = head[u];
    head[u] = tot++;
}

void SPFA(int Min, int Max)
{
    int i;
    for ( i = Min;i <= Max; i++ )
    {
        d[i] = INF;
        vis[i] = 0;
    }
    queue<int> q;
    q.push(Max);
    d[Max] = 0;
    vis[Max] = 1;
    while ( !q.empty() )
    {
        int u = q.front();
        q.pop();
        vis[u] = false;
        for ( i = head[u]; i != -1; i = E[i].next)
        {
            int v = E[i].to;
            if (d[v] > d[u] + E[i].dist)
            {
                d[v] = d[u] + E[i].dist;
                if (!vis[v])
                {
                    vis[v] = true;
                    q.push(v);
                }
            }
        }
    }
}

void solve()
{
    memset( head, -1, sizeof(head) );
    tot = 0;
    int Min = INF, Max = -INF;
    int u, v, i, h;
    for ( i = 0;i < n; i++ )
    {
        scanf ( "%d %d %d", &u, &v, &h );
        Min = min(Min, u);
        Max = max(Max, v+1);
        AddEdge(v+1, u, -h);
    }
    for ( i = 0;i < Max; i++ )
    {
        AddEdge(i, i+1, 1);
        AddEdge(i+1, i, 0);
    }
    SPFA(Min, Max);
    printf ( "%d\n", d[Max] - d[Min] );
}

int main()
{
    while ( ~scanf ( "%d", &n ) )
    {
        solve();
    }
    return 0;
}

代碼菜鳥,如有錯誤,請多包涵!!!

如有幫助記得支持我一下,謝謝!!!


發佈了222 篇原創文章 · 獲贊 29 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章