POJ 1716 Integer Intervals 差分约束系统

来源:互联网 发布:淘宝红包雨怎么能抢上 编辑:程序博客网 时间:2024/04/27 10:58
/** * @file main.cpp * @brief 差分约束系统,也可以用贪心来做 *        贪心的方法是按照[a,b]的b进行排序,然后贪心 * *        差分约束条件为 *        1. s[b] - s[a] >= 2 *        2. s[i] - s[i - 1] >= 0 *        3. s[i] - s[i - 1] <= 1 * *        即转换为 *        1. if (s[a] + 2 > s[b]) *              s[b] = s[a] + 2 *        2. if (s[i - 1] + 0 > s[i]) *              s[i] = s[i - 1] + 0 *        3. if (s[i] + (-1) > s[i - 1]) *              s[i - 1] = s[i] + (-1) * *        因此,构图为: *        1. (a, b)添加权为2的边 *        2. (i - 1, i)添加权为0的边 *        3. (i, i - 1)添加权为-1的边 * * * @author yekeren * @version 1.0.0 * @date 2013-06-06 */#include <iostream>#include <queue>#define MAX_INT 0x7fffffff#define LIMIT 10002///(M)临接表struct edge_t {    int b, c;    struct edge_t *next;};edge_t *k[LIMIT] = { NULL };edge_t pool[LIMIT * 4];int npool = 0;/** * @brief 临接表添加边  * @param a * @param b * @param c */void add_edge(int a, int b, int c){    pool[npool].b = b;    pool[npool].c = c;    pool[npool].next = k[a];    k[a] = &pool[npool++];}/** * @brief shortest path faster algorithm  * @param imin * @param imax * @return    */int spfa(int imin, int imax){    int s[LIMIT] = { 0 };    for (int i = 0; i <= imax; ++i) {        s[i] = - MAX_INT;    }    unsigned char visit[LIMIT] = { 0 };    std::queue<int> q;    visit[imin] = 1;    q.push(imin);    s[imin] = 0;    while (!q.empty())    {        int u = q.front();        visit[u] = 0;        q.pop();        for (edge_t *p = k[u]; p != NULL; p = p->next)        {            int v = p->b;            int c = p->c;            if (s[u] + c > s[v])             {                s[v] = s[u] + c;                if (!visit[v])                 {                    visit[v] = 1;                    q.push(v);                }            }        }    }    return s[imax];}int main(int argc, char *argv[]){    int n;    std::cin >> n;    int imax = 0;    int imin = MAX_INT;    for (int i = 0; i < n; ++i)    {        int a, b;        std::cin >> a >> b;        ++b;        if (a < imin) {            imin = a;        }        if (b > imax) {            imax = b;        }        add_edge(a, b, 2);    }    for (int i = imin; i < imax; ++i)    {        add_edge(i, i + 1, 0);        add_edge(i + 1, i, -1);    }    std::cout << spfa(imin, imax) << std::endl;    return 0;}

原创粉丝点击