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写的:
代码
已知一个序列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; }
相关文章推荐
- PKU 1364 KING【差分约束系统】
- POJ 1364 King ( 差分约束系统 )
- POJ 1364 King(差分约束系统)
- pku2983 差分约束系统(SPFA + 栈)
- pku 1201 Intervals(差分约束系统)
- pku 2983 Is the Information Reliable?(差分约束系统)
- POJ - 1364 King (差分约束系统)
- 差分约束 1:pku 1201 Intervals 2:pku 1364 King 3:hdu 1534
- pku3169 差分约束系统
- pku 1364 King(差分约束)
- POJ 1364 King(差分约束系统)
- pku 3159 Candies 第一道Dijkstra+堆维护+差分约束系统的题目
- 【POJ 1364】King(差分约束系统)
- POJ 1364-King(差分约束系统)
- POJ 1364 King(差分约束系统+bellmanford)
- POJ 1364 King [差分约束系统]
- POJ 1364 King (差分约束系统)
- POJ 1364 King(差分约束系统)
- [POJ1364]King(差分约束系统)
- poj 1364 KING (差分约束系统)