码迷,mamicode.com
首页 > 其他好文 > 详细

poj 1201 TYVJ 1415 Intervals

时间:2018-04-01 00:01:17      阅读:232      评论:0      收藏:0      [点我收藏+]

标签:main   def   click   gif   ges   起点   sub   集合   play   

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

 

poj 1201 TYVJ 1415 Intervals

标签:main   def   click   gif   ges   起点   sub   集合   play   

原文地址:https://www.cnblogs.com/Rorshach/p/8684714.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!