zoukankan      html  css  js  c++  java
  • POJ 1201 Intervals (差分约束+SPFA)

    Intervals
    Time Limit: 2000MS   Memory Limit: 65536K
    Total Submissions: 18595   Accepted: 6976

    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

    Source

    题意: 在区间[0,50000]上有一些整点,并且满足n个约束条件(u, v, w),即在区间[u, v]上至少有x个整点,问区间[0, 50000]上至少有几个整点。

    假设不等式 x1-x2<=d  => x1<=x2+d,这种形式是不是很像最短路径中的更新操作,当x1>x2+d 的时候就必须更新 即d[u]>d[v]+w的时候就要松弛时一样的道理。

    这道题的题意很好理解我们只要找到两个约束条件:

    Sbi+1-Sai>=ci;

    1>= Si+1-Si >=0;(Si+1-Si>=0; Si-Si+1>=-1)

    注意这里是>=也就是如果是<就要更新,那么是不是最长路呢。

    其中Si,是表示,[0,i-1]这个区间和我们要求的序列的共同值的个数,为什么要加1,是避免0的情况。

    从不等式中易想到差分限制系统
      即若a-b>=c,建立从b指向a的边,边的权重为c,

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    
    using namespace std;
    
    const int VM=50010;
    const int INF=0x3f3f3f3f;
    
    struct Edge{
        int to,nxt;
        int cap;
    }edge[VM<<2];   //注意这里的范围不能太小,否则WA
    
    int n,cnt,head[VM],src,des;
    int dis[VM],vis[VM];
    
    void addedge(int cu,int cv,int cw){
        edge[cnt].to=cv;    edge[cnt].cap=cw;   edge[cnt].nxt=head[cu];
        head[cu]=cnt++;
    }
    
    int SPFA(){
        queue<int> q;
        while(!q.empty())
            q.pop();
        memset(vis,0,sizeof(vis));
        for(int i=src;i<=des;i++)
            dis[i]=-INF;
        dis[src]=0;
        vis[src]=1;
        q.push(src);
        while(!q.empty()){
            int u=q.front();
            q.pop();
            vis[u]=0;
            for(int i=head[u];i!=-1;i=edge[i].nxt){
                int v=edge[i].to;
                if(dis[v]<dis[u]+edge[i].cap){
                    dis[v]=dis[u]+edge[i].cap;
                    if(!vis[v]){
                        vis[v]=1;
                        q.push(v);
                    }
                }
            }
        }
        return dis[des];
    }
    
    int main(){
    
        //freopen("input.txt","r",stdin);
    
        while(~scanf("%d",&n)){
            cnt=0;
            memset(head,-1,sizeof(head));
            src=VM, des=0;
            int u,v,w;
            while(n--){
                scanf("%d%d%d",&u,&v,&w);
                addedge(u,v+1,w);     //  一般为(u - 1, v, w),但这道题为了防止溢出用v + 1。
                src=min(src,u);
                des=max(des,v+1);
            }
            for(int i=src;i<=des;i++){  //两个隐含的约束条件,即1 >= dis[i] - dis[i-1] >= 0,
                addedge(i,i+1,0);   // dis[i] >= dis[i-1] + 0(正向边
                addedge(i+1,i,-1);  // dis[i-1] - dis[i] >= -1 (反向边)
            }
            printf("%d\n",SPFA());
        }
        return 0;
    }
  • 相关阅读:
    可爱的中国电信 请问我们的电脑还属于我们自己吗?
    了解客户的需求,写出的代码或许才是最优秀的............
    DELPHI DATASNAP 入门操作(3)简单的主从表的简单更新【含简单事务处理】
    用数组公式获取字符在字符串中最后出现的位置
    在ehlib的DBGridEh控件中使用过滤功能(可以不用 MemTableEh 控件 适用ehlib 5.2 ehlib 5.3)
    格式化json返回的时间
    ExtJs中使用Ajax赋值给全局变量异常解决方案
    java compiler level does not match the version of the installed java project facet (转)
    收集的资料(六)ASP.NET编程中的十大技巧
    收集的资料共享出来(五)Asp.Net 权限解决办法
  • 原文地址:https://www.cnblogs.com/jackge/p/3017063.html
Copyright © 2011-2022 走看看