POJ 3169 Layout 差分约束系统

本文深入介绍了差分约束系统的概念,包括如何通过建图将不等式转化为求最短路或最长路的问题,详细解释了求最小差和最大差的方法,并提供了几个经典案例的链接供读者参考。此外,文章还分享了在解决此类问题时,SPFA和Dijkstra算法的选择依据,以及在实际应用中如何提高算法效率的技巧。

介绍下差分约束系统:就是多个2未知数不等式形如(a-b<=k)的形式

                            问你有没有解,或者求两个未知数的最大差或者最小差

                            转化为最短路(或最长路)

                            1:求最小差的时候,不等式转化为b-a>=k的标准形式建图,求最长路

                            2:求最大差的时候,不等式转化为b-a<=k的标准形式建图,求最短路

然后具体的写的好的博客以供大家参考

             1 http://www.cnblogs.com/void/archive/2011/08/26/2153928.html

             2 http://blog.youkuaiyun.com/zhang20072844/article/details/7788672

             3 http://www.cnblogs.com/pony1993/archive/2012/09/01/2666996.html

注:由于spfa比较慢,所以全是正权的时候用dij,负权用spfa,写spfa的时候,有时候用堆栈写起来更快(我也不知道为啥,当然手写的更快)

代码:

#include<cstdio>
#include<cstring>
#include<queue>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
typedef long long LL;
const int N=1e3+5;
const int INF=0x3f3f3f3f;
struct Edge{
   int v,w,next;
}edge[12000];
bool inq[N];
int tot,n,ml,md,head[N],d[N],cnt[N];
void add(int u,int v,int w){
  edge[tot].v=v;
  edge[tot].w=w;
  edge[tot].next=head[u];
  head[u]=tot++;
}
queue<int>q;
bool spfa(int s){
  for(int i=1;i<=n;++i)
    d[i]=INF,cnt[i]=0,inq[i]=0;
  while(!q.empty())q.pop();
  d[s]=0;
  q.push(s),cnt[s]=1,inq[s]=true;
  while(!q.empty()){
    int u=q.front();
    q.pop();
    inq[u]=false;
    for(int i=head[u];~i;i=edge[i].next){
      int v=edge[i].v;
      if(d[v]>d[u]+edge[i].w){
        d[v]=d[u]+edge[i].w;
        if(!inq[v]){
           q.push(v);
           inq[v]=1;
           ++cnt[v];
           if(cnt[v]>n)return false;
        }
      }
    }
  }
  return true;
}
int main(){ 
    scanf("%d%d%d",&n,&ml,&md);
    memset(head,-1,sizeof(head));
    for(int i=1;i<=ml;++i){
      int u,v,w;
      scanf("%d%d%d",&u,&v,&w);
      add(u,v,w);
    }
    for(int i=1;i<n;++i)add(i+1,i,0);
    for(int i=1;i<=md;++i){
      int u,v,w;
      scanf("%d%d%d",&u,&v,&w);
      add(v,u,-w);
    }
    if(!spfa(1))printf("-1\n");
    else{
      if(d[n]==INF)printf("-2\n");
      else printf("%d\n",d[n]);
    }
    return 0;
}
View Code

 

转载于:https://www.cnblogs.com/shuguangzw/p/5333687.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值