首页 > 代码库 > POJ 1364 King --差分约束第一题
POJ 1364 King --差分约束第一题
题意:求给定的一组不等式是否有解,不等式要么是:SUM(Xi) (a<=i<=b) > k (1) 要么是 SUM(Xi) (a<=i<=b) < k (2)
分析:典型差分约束题,变换,令Ti = SUM(Xj) (0<=j<=i). 则表达式(1)可以看做T(a+b)-T(a-1) > k,也就是T(a-1)-T(a+b) < -k,又因为全是整数,所以T(a-1)-T(a+b) <= -k-1. 同理,(2)看做T(a+b)-T(a-1) <= k-1.这样就化成了差分约束系统的题了。
在差分约束系统中,Xi - Xj <= K 的表达式建边为 <Xj,Xi> = K.
不存在这个序列的情况即为出现负环,所以这题建图后只需判断有无负环即可。这里用Bellman-Ford算法判负环
注意:
(1)a-1有可能为0,a+b有可能为n,所以如果按顶点来遍历边的话有n+1个顶点(0~n)。
(2)建的图可能不连通,可以通过附加点来使图联通,即令dis[] = {0}。相当于每个点都与一个附加点Vs相连,且边权为0.
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #define Mod 1000000007 using namespace std; #define N 107 struct Edge { int v,next,w; }G[N]; int head[N],tot; int dis[N]; int n,m; void addedge(int u,int v,int w) { G[tot].v = v; G[tot].w = w; G[tot].next = head[u]; head[u] = tot++; } bool Bellman_Ford() { int i,j,k; memset(dis,0,sizeof(dis)); for(i=0;i<=n;i++) //n+1个节点 { for(j=0;j<=n;j++) { for(k=head[j];k!=-1;k=G[k].next) { int v = G[k].v; int w = G[k].w; if(dis[v] > dis[j] + w) dis[v] = dis[j] + w; } } } for(j=0;j<=n;j++) { for(k=head[j];k!=-1;k=G[k].next) { int v = G[k].v; int w = G[k].w; if(dis[v] > dis[j] + w) return false; } } return true; } int main() { int u,v,w,i; char ss[5]; while(scanf("%d",&n)!=EOF && n) { scanf("%d",&m); tot = 1; memset(head,-1,sizeof(head)); for(i=0;i<m;i++) { scanf("%d%d%s%d",&u,&v,ss,&w); if(ss[0] == ‘g‘) addedge(u+v,u-1,-w-1); else addedge(u-1,u+v,w-1); } if(!Bellman_Ford()) puts("successful conspiracy"); else puts("lamentable kingdom"); } return 0; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。