zoukankan      html  css  js  c++  java
  • Intervals(差分约束系统)

    http://poj.org/problem?id=1201

    题意:给定n个整数闭区间[a,b]和n个整数c,求一个最小的整数集合Z,满足Z里边的数中范围在闭区间[a,b]的个数不小于c个。

    思路:根据题目描述,可建模成一个差分约束系统。

    设S[i]表示小于等于i的整数的个数,R表示最大的右端点值,L表示最小的左端点值:

    则 S[b] - S[a-1] >= c;

    转化成:S[a-1] - S[b] <= -c;...... (1)

               S[i] - S[i-1]  <= 1; ........ (2)

    S[i] -S[i-1] >= 0;

    转化成:S[i-1] - S[i]  <= 0;.......... (3)   

    (1)(2)(3)即为三个约束条件。最终要求的就是S[R] - S[L-1] >= M,即 S[L-1] - S[R] <= -M;

     1 #include <stdio.h>
     2 #include <string.h>
     3 const int N=50005;
     4 const int INF=1<<28;
     5 struct node
     6 {
     7     int u,v,w;
     8 } edge[N];
     9 int dis[N];
    10 int n,cnt,l,r;//l表示所有左端点的最小值,r表示所有右端点的最大值
    11 void add(int u,int v,int w)
    12 {
    13     edge[cnt].u = u;
    14     edge[cnt].v = v;
    15     edge[cnt++].w = w;
    16 }
    17 bool bellman_ford()
    18 {
    19     memset(dis,0,sizeof(dis));
    20     int flag = 1;//只要某次循环过程中,没能改变源点到各顶点的最短距离,则可以提前结束循环
    21     while(flag)
    22     {
    23         flag = 0;
    24         for (int i = 0; i < n; i++)
    25         {
    26             int u = edge[i].u;
    27             int v = edge[i].v;
    28             if (dis[v] > dis[u]+edge[i].w)
    29             {
    30                 dis[v] = dis[u]+edge[i].w;
    31                 flag = 1;
    32             }
    33         }
    34         for (int i = l; i <= r; i++)//根据约束条件s[i] <= s[i-1]+1,进一步修改s[i];
    35         {
    36             if (dis[i-1]+1 < dis[i])
    37             {
    38                 dis[i] = dis[i-1]+1;
    39                 flag = 1;
    40             }
    41         }
    42         for (int i = r; i >= l; i--)//根据约束条件S[i] >= s[i-1],进一步修改s[i-1];
    43         {
    44             if (dis[i] < dis[i-1])
    45             {
    46                 dis[i-1] = dis[i];
    47                 flag = 1;
    48             }
    49 
    50         }
    51     }
    52     return true;
    53 }
    54 int main()
    55 {
    56     int a,b,c;
    57     while(~scanf("%d",&n))
    58     {
    59         cnt = 0,r = 0,l = INF;
    60         for (int i = 0; i < n; i++)
    61         {
    62             scanf("%d %d %d",&a,&b,&c);
    63             add(b,a-1,-c);//构造边
    64             if (l > a)
    65                 l = a;//左端点的最小值
    66             if (r < b)
    67                 r = b;//右端点的最小值
    68         }
    69         bellman_ford();
    70         printf("%d
    ",dis[r]-dis[l-1]);
    71     }
    72     return 0;
    73 }
    View Code
  • 相关阅读:
    spring集成环境下的axis webservice的发布,调试
    Axis2 webservice 之使用java调用webservice
    Axis2 webservice入门--写个简单的webservice
    Axis2 webservice入门--开发环境搭建,概念理解
    使用js给页面显示的图片添加水印效果
    java使用dom4j解析xml文件
    一个Java递归程序
    Java-Scanner键盘输入
    JVM—调优参数学习
    JVM—类加载过程
  • 原文地址:https://www.cnblogs.com/lahblogs/p/3439971.html
Copyright © 2011-2022 走看看