/**
* @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;
}
POJ 1716 Integer Intervals 差分约束系统
最新推荐文章于 2018-09-15 10:11:08 发布