• zoj 1508 差分约束 Bellman-Ford


    Intervals

    Time Limit: 10 Seconds      Memory Limit: 32768 KB

    You are given n closed, integer intervals [ai, bi] and n integers c1, ..., cn.

    Write a program that:

    > reads the number of intervals, their endpoints 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 <= 50 000) - 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 <= 50 000 and 1 <= ci <= bi - ai + 1.

    Process to the end of file.


    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: Southwestern Europe 2002

    参考了《数与图的完美结合--浅析差分约束系统》,by 张威:http://pan.baidu.com/share/link?shareid=508660&uk=2720516383&fid=743287535

    对属于区间[ai, bi]的任意元素,按属于于不属于题述序列关系,可定义如下映射:

    t=0,表某元素不在序列中;1,表在序列中。

    则可令Si= 从ai-1到bi,求和(t),即Si表该区间[ai,bi]中在序列的元素个数。至此,不难构造不等式(组):

    S(bi)-S(ai-1)>=ci;另外由任意S(i)与S(i-1)的关系也可得:

    0<=S(i)-S(i-1)<=1; 转化为:

    S(ai-1) - S(bi) <= -ci

    S(i-1) - S(i) <= 0

    S(i) - S(i-1) <= 1

    于是就可以直接建图用bellmanford算法了,但答案是多少呢?这里我不很清楚,可能是这样建图产生负权边,然后求相对值吧。论文给出的是d[最大节点标号]-d[最小节点标号,即0].

    AC代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<string>
     5 #include<cmath>
     6 #include<vector>
     7 #include<cstdlib>
     8 #include<algorithm>
     9 #include<queue>
    10 
    11 using namespace std;
    12 
    13 #define LL long long
    14 #define ULL unsigned long long
    15 #define UINT unsigned int
    16 #define MAX_INT 0x7fffffff
    17 #define MAX_LL 0x7fffffffffffffff
    18 #define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
    19 #define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
    20 
    21 #define MAXN 66666
    22 #define MAXM 200000
    23 #define INF 100000
    24 
    25 struct edge{
    26     int u,v,nxt,w;
    27 }e[MAXM];
    28 int cc,h[MAXN];
    29 int inq[MAXN],d[MAXN];
    30 int ans;
    31 
    32 inline void add(int u, int v, int w){
    33     e[cc]=(edge){u,v,h[u],w};
    34     h[u]=cc++;
    35 }
    36 
    37 queue<int> q;
    38 int bford(int s, int n){
    39     int u,i,w,v;
    40     while(!q.empty()) q.pop();  q.push(s);
    41  //   memset(cnt, 0, sizeof(cnt));    cnt[s]=1;
    42     memset(inq, 0, sizeof(inq));    inq[s]=1;
    43     for(i=0; i<n; i++) d[i]=INF;    d[s]=0;
    44     while(!q.empty()){
    45         u=q.front();    q.pop();    inq[u]=0;
    46         for(i=h[u]; i!=-1; i=e[i].nxt){
    47             v=e[i].v;
    48             w=e[i].w;
    49             if(d[v]>d[u]+w){
    50                 d[v]=d[u]+w;
    51                 if(!inq[v]){
    52     //                if(++cnt[v]>n) return 1;
    53                     q.push(v);
    54                     inq[v]=1;
    55                 }
    56             }
    57         }
    58     }
    59     ans=d[s-1]-d[0];            // 结果不是d[s-1]么?。。。
    60     return 0;
    61 }
    62 
    63 #define POINT(x) ((x) < 0 ? 0 : (x) )
    64 
    65 int main(){
    66 //  freopen("C:\Users\Administrator\Desktop\in.txt","r",stdin);
    67     int n;
    68     while(scanf(" %d",&n)==1){
    69         int a,b,c;
    70         int i,ub=0;
    71         cc=0;
    72         memset(h, -1, sizeof(h));
    73         for(i=0; i<n; i++){
    74             scanf(" %d %d %d",&a,&b,&c);
    75             add(b, POINT(a-1), -c);         // S(bi) - S(ai-1) <= C(i) --如果a-1<0,则用0代替a-1,仍满足,此时0表示ai-1项不存在
    76             ub=MAX(ub, b);                  // 记录最大点编号
    77         }
    78         ub++;
    79         for(i=1; i<ub; i++){
    80             add(i, i-1, 0);                 // S(i-1) - S(i) <= 0
    81             add(i-1, i, 1);                 // S(i) - S(i-1) <= 1
    82         }
    83         for(i=0; i<ub; i++) add(ub, i, 0);  // S(ub+1) - i <= 0  --虚拟源点,编号ub+1
    84 
    85         bford(ub, ub+2);                    // 共有ub+2个点
    86         printf("%d
    ", ans);
    87     }
    88     return 0;
    89 }
    View Code
  • 相关阅读:
    WeChat小程序开发(五、前端总结)
    前端实现复制到剪贴板
    vue的自定义指令含大写字母会失效
    如何把网页变成黑白
    原生JS offsetX和offsetY引起抖动
    jQuery中prop方法和attr方法区别
    Js for循环中的闭包 & let和var的混用对比
    html和body标签默认高度为0带来的影响
    JS字符串数组降维
    CSS浮动流脱标的字围现象
  • 原文地址:https://www.cnblogs.com/ramanujan/p/3280245.html
Copyright © 2020-2023  润新知