poj 1201 TYVJ 1415 Intervals

Description:

  给定n个闭区间[ai,bi] 和n个整数ci,你需要构造一个集合Z,使得对于任何的i∈[1,n],Z中满足x∈[ai,bi]的x不少于ci个 求这样的整数集合Z至少包含多少个数

 

思路:建立差分约束系统的模型s[k]表示0~k间选取多少个整数,根据题意有s[bi] -  s[ai - 1] ≥ c

不过还要增加一些隐含条件   s[k] - s[k - 1] ≥ 0,s[k]  - s[k  -1] ≤ 1

因此,将输入最大的数bi作为图中的节点,从每个k - 1到k连长度为0的有向边,k到k - 1连长度为 -1 的有向边。从每个到ai - 1 到 bi 连长度为ci的有向边

起点为0,终点为max(bi

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
const int N = 50050, M = 1e6 + 10;
typedef pair<int,int> P;

int head[N], now;
struct edges{
    int to, next, w;
}edge[M<<1];
void add(int u, int v, int w){ edge[++now] = {v, head[u], w}; head[u] = now;}

int n, d[N], s;
bool vis[N];
queue<int> q;
void spfa(){
    d[s] = 0;
    q.push(s);
    vis[s] = 1;
    while(!q.empty()){
        int x = q.front(); q.pop();
        vis[x] = 0;
        for(int i = head[x]; i; i = edge[i].next){
            int v = edge[i].to;
            if(d[v] < d[x] + edge[i].w || (d[v] == d[x] + edge[i].w && v == x + 1)){
                d[v] = d[x] + edge[i].w;
                if(!vis[v]) q.push(v), vis[v] = 1;
            }
        }
    }
}
int main(){
    scanf("%d", &n);
    int x, y, z;
    int mx = 0;
    for(int i = 1; i <= n; i++){
        scanf("%d%d%d", &x, &y, &z);
        x++, y++;  // 全都向上加1,防止数组向下溢出 
        mx = max(mx, y);
        add(x - 1, y, z);
    }
    for(int i = 1; i <= mx; i++)
      add(i - 1, i, 0), add(i, i - 1, -1);
    s = 0;
    spfa();
    printf("%d\n",d[mx]);
    return 0;
}
View Code

 

posted @ 2018-03-31 23:22  Ror_shach  阅读(167)  评论(0编辑  收藏  举报