您的位置:首页 > 其它

POJ 1364 King (差分约束系统)

2012-07-24 17:34 435 查看
题目描述有点复杂,前面讲了一大堆废话。

题目大意:对一个含n个整数的序列进行一些约束:

1、整数序列中连续的一段的和大于某个整数;

2、整数序列中连续的一段的和小于某个整数。

问满足以上约束的整数序列是否存在。

分析:首先利用前缀和进行转换,然后将>化为>=,将<化为<=,然后就基本是裸的差分约束系统了。

需要注意的是,建立的约束图可能并不是无向连通的,所以需要另外加一个结点作为源点,由于加了一个点,所以判断是否有负环时要注意,条件是某个点进队次数大于n+1

View Code

#include <stdio.h>
#include <string.h>
#include <queue>
using namespace std;
#define N 110
#define M 210
#define INF 0x3fffffff
int n,m;
int d
;
int inq
,cnt
;
int first
,v[M],next[M],w[M];
int e;
void init()
{
e=0;
memset(first,-1,sizeof(first));
}
void insert(int a,int b,int c)
{
v[e]=b;
w[e]=c;
next[e]=first[a];
first[a]=e++;
}
void spfa()
{
queue<int> q;
int a,b;
bool loop=false;

memset(inq,0,sizeof(int)*(n+5));
memset(cnt,0,sizeof(int)*(n+5));

for(int i=0;i<=n;i++)   d[i]=INF;
d[n+1]=0;
inq[n+1]=1;
q.push(n+1);
cnt[n+1]++;
while(!q.empty())
{
a=q.front(),q.pop();
if(cnt[a]>n+1)   { loop=true;    break; }
inq[a]=0;
for(int i=first[a];i!=-1;i=next[i])
{
b=v[i];
if(d[b]>d[a]+w[i])
{
d[b]=d[a]+w[i];
if(inq[b]==0)   inq[b]=1,q.push(b),cnt[b]++;
}
}
}
if(loop)    puts("successful conspiracy");
else   puts("lamentable kingdom");
}
int main()
{
int i;
int a,b,c;
char s[5];
while(scanf("%d",&n),n)
{
init();
scanf("%d",&m);
for(i=0;i<m;i++)
{
scanf("%d%d%s%d",&a,&b,s,&c);
if(s[0]=='g')
{
insert(a+b,a-1,-c-1);
}
else
{
insert(a-1,a+b,c-1);
}
}
for(i=0;i<=n;i++) insert(n+1,i,0);
spfa();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: