您的位置:首页 > 其它

pku1364 差分约束系统

2010-07-20 10:43 211 查看
King

已知一个序列a[1], a[2], ......, a
,给出它的若干子序列以及对该子序列的约束条件,例如a[si], a[si+1], a[si+2], ......, a[si+ni],且a[si]+a[si+1]+a[si+2]+......+a[si+ni] < or > ki。问题关键在于如何转化约束条件,开始我想以序列中的每一个值做一个点,如a[1], a[2] ……,就发现他们的关系是多者之间的关系,跟差分系统对不上,在看到MickJack的讲解后,才知道,用前n项和来转化成两两之间的关系。

如:s[a] + s[a+1] + …… + s[b] < c 可以转化成前n项和sum[b] - sum[a - 1] < c,为了能用Bellman_Ford,即将< 转化成 <= ,sum[b] - sum[a - 1] <= c - 1。

我用Bellman_Ford写的:

代码

#include<stdio.h>
#include<string.h>
#define INF 0xfffffff
#define NN 106
int index, n;
int dis[NN];  /* 保存到源点距离,在这里没有设源,没有含义 */
int root[NN]; /* root[i] 找到与i节点相连的第一条后继边 */
int mark[NN]; /* 标记是否已入队 */
int next[NN]; /* 邻接的下一个定点 */
int cnt[NN];  /* 保存节点入队次数 */
struct node{
int e, v;
}edge[NN];

void add(int a, int b, int c){
int head, tmp;
edge[index].e = b;
edge[index].v = c;
head = root[a];
//key1
if (head == -1){
root[a] = index;
}else{
tmp = head;
while (next[tmp] != -1){
tmp = next[tmp];
}
next[tmp] = index;
}
next[index] = -1;
index++;
}

void Init(){
int i;
for (i = 0; i <= n; i++){
dis[i] = INF;
}
}

/*查找负边权回路,1表示存在*/
int Spfa(){
int i, len, cur, tmp, head, nxt;
int que[NN];
Init();
len = 0;
//key2
for (i = 0; i <= n; i++){
if (root[i] != -1){
que[len++] = i;
cnt[i] = 1;
mark[i] = 1;
}
}
//key3
for (i = 0; i != len; i = (i + 1) % (n + 2)){
cur = que[i];
head = root[cur];
tmp = head;
while (tmp != -1){
nxt = edge[tmp].e;
if (dis[nxt] > dis[cur] + edge[tmp].v){
dis[nxt] = dis[cur] + edge[tmp].v;

if (!mark[nxt]){
mark[nxt] = 1;
cnt[nxt]++;
que[len] = nxt;
len = (len + 1) % (n + 2);
//key4
if (cnt[nxt] > n + 1) return 1;
}
}
tmp = next[tmp];
}
mark[cur] = 0;
}
return 0;
}

int main()
{
char str[4];
int a, b, c, m;
while (scanf("%d", &n) != EOF){
if (n == 0) break;
scanf("%d", &m);
index = 0;
memset(root, -1, sizeof(root));
while (m--){
scanf("%d%d%s%d", &a, &b, str, &c);
if (str[0] == 'l'){
add(a - 1, a + b, c - 1);
}else{
add(a + b, a - 1, -c - 1);
}
}
memset(cnt, 0, sizeof(cnt));
memset(mark, 0, sizeof(mark));

if(Spfa()) puts("successful conspiracy");
else puts("lamentable kingdom");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: