# POJ 1201 Intervals (差分约束系统）

1.假设区间z=[s,t]， sum[i]表示[s,t] ∩ [s,i] 的元素个数。那么[ai,bi] >= ci 则可以表示为sum[bi]-sum[ai-1]>=ci。
2.若i<=j,则 [s,t] ∩ [s,i] 的元素个数 <= [s,t] ∩ [s,j] 的元素个数，即：sum[i] <= sum[j]
3.若i<=j,则 sum[j] - sum[i] <= j-i

//AC
#include <iostream>
using namespace std;

#define N  100009
#define INF 999999

bool mark[N];
int m, size, lmin, rmax;

struct Edge { int v, w, next; };
Edge  edge[N*3];

void Spfa()
{
memset(mark,0,sizeof(mark));
for ( int i = lmin; i <= rmax; i++ )
dis[i] = INF;

int u, v, front, rear;
front = rear = 0;
que[rear] = rmax+1;
rear = ( rear + 1 ) % N;
mark[rmax+1] = true;
dis[rmax+1] = 0;

while ( front != rear )
{
u = que[front];
front = ( front + 1 ) % N;
mark[u] = false;
for ( int i = head[u]; i; i = edge[i].next )
{
v = edge[i].v;
if ( dis[v] > dis[u] + edge[i].w )
{
dis[v] = dis[u] + edge[i].w;
if ( ! mark[v] )
{
que[rear] = v;
rear = ( rear + 1 ) % N;
mark[v] = true;
}
}
}
}
}

void add ( int u, int v, int w )
{
size++;
edge[size].v = v;
edge[size].w = w;
}

int main()
{
int a, b, c, i;
scanf("%d",&m);
size = 0;
lmin = INF; rmax = -INF;

while ( m-- )
{
scanf("%d%d%d",&a,&b,&c);
add ( b+1, a, -c );
if ( a < lmin ) lmin = a;
if ( b+1 > rmax ) rmax = b+1;
}

for ( i = lmin; i < rmax; i++ )
{
add ( i+1, i, 0 );
add ( i, i+1, 1 );
}

for ( i = lmin; i <= rmax; i++ )
add ( rmax+1, i, 0 );

Spfa();
printf("%d\n",dis[rmax]-dis[lmin]);

return 0;
}


1.上面的代码添加了超级源点，所以可以保证图的连通性，解出来的答案也没问题。
//AC
#include <iostream>
using namespace std;

#define N  100009
#define INF 999999

bool mark[N];
int m, size, lmin, rmax, s;

struct Edge { int v, w, next; };
Edge  edge[N*3];

void Spfa()
{
memset(mark,0,sizeof(mark));
for ( int i = lmin; i <= rmax; i++ )
dis[i] = INF;

s = rmax;              // 换成lmin则错误 ！！！
int u, v, front, rear;
front = rear = 0;
que[rear] = s;
rear = ( rear + 1 ) % N;
mark[s] = true;
dis[s] = 0;

while ( front != rear )
{
u = que[front];
front = ( front + 1 ) % N;
mark[u] = false;
for ( int i = head[u]; i; i = edge[i].next )
{
v = edge[i].v;
if ( dis[v] > dis[u] + edge[i].w )
{
dis[v] = dis[u] + edge[i].w;
if ( ! mark[v] )
{
que[rear] = v;
rear = ( rear + 1 ) % N;
mark[v] = true;
}
}
}
}
}

void add ( int u, int v, int w )
{
size++;
edge[size].v = v;
edge[size].w = w;
}

int main()
{
int a, b, c, i;
scanf("%d",&m);
size = 0;
lmin = INF; rmax = -INF;

while ( m-- )
{
scanf("%d%d%d",&a,&b,&c);
add ( b+1, a, -c );
if ( a < lmin ) lmin = a;
if ( b+1 > rmax ) rmax = b+1;
}

for ( i = lmin; i < rmax; i++ )
{
add ( i+1, i, 0 );
add ( i, i+1, 1 );
}

//	for ( i = lmin; i <= rmax; i++ )
//	add ( rmax+1, i, 0 );

Spfa();
printf("%d\n",dis[rmax]-dis[lmin]);

return 0;
}


• 评论

• 上一篇
• 下一篇