zoukankan      html  css  js  c++  java
  • POJ 3169 Layout 【差分约束】+【spfa】

    <题目链接>

    题目大意:

    一些母牛按序号排成一条直线。有两种要求,A和B距离不得超过X,还有一种是C和D距离不得少于Y,问可能的最大距离。如果没有最大距离输出-1,如果1、n之间距离任意就输出-2,否则输出最大的距离。

    解题分析:
    典型的差分约束,第一种约束,v-u<=c;第二种约束:v-u>=c  可以转化为 u-v<=c ,还有一种约束,因为题目要求按序号排序,所以 loc[i] - loc[i-1]>=0 ,即 loc[i-1]-loc[i]<=0 。以上就是本题的三种约束,利用上述三种约束建图,然后跑一遍最短路即可,因为可能存在负权边,所以用spfa求解。当该图存在负环的时候输出-1,当1~n不连通的时候输出-2,否则输出1---->n的最短边权约束和。即所求的最大距离。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <queue>
     4 #include <algorithm>
     5 using namespace std;
     6 
     7 const int N =1e3+10;
     8 const int M =2e5+10;
     9 #define INF 0x3f3f3f3f
    10 struct EDGE{
    11     int to,val,next;
    12 }edge[M];
    13 int head[N],dis[N],cnt[N],tot,n,ml,md;
    14 bool vis[N];
    15 
    16 void init(){
    17     memset(head,-1,sizeof(head));
    18     tot=0;
    19 }
    20 void add(int u,int v,int w){
    21     edge[++tot].to=v,edge[tot].val=w;
    22     edge[tot].next=head[u],head[u]=tot;
    23 }
    24 int spfa(int s){   //因为存在负权边,所以用spfa求最短路
    25     memset(dis,INF,sizeof(dis));
    26     memset(vis,false,sizeof(vis));
    27     memset(cnt,0,sizeof(cnt));
    28     queue<int>q;
    29     q.push(s);
    30     vis[s]=true,cnt[s]=1,dis[s]=0;
    31     while(!q.empty()){
    32         int cur=q.front();
    33         q.pop();
    34         vis[cur]=false;
    35         for(int i=head[cur];~i;i=edge[i].next){
    36             int v=edge[i].to;
    37             if(dis[v]>dis[cur]+edge[i].val){
    38                 dis[v]=dis[cur]+edge[i].val;
    39                 if(!vis[v]){
    40                     vis[v]=true;
    41                     if(++cnt[v]>n)return -1;   //进队列次数>n,说明存在负环,直接返回-1
    42                     q.push(v);
    43                 }
    44             }
    45         }
    46     }
    47     if(dis[n]==INF)return -2;    //如果两点不连通,说明1、n两点之间没有约束条件,所以1、n可以距离任意远,返回-2
    48     return dis[n];
    49 }
    50 int main(){
    51     while(scanf("%d%d%d",&n,&ml,&md)!=EOF){
    52         init();
    53         for(int i=1;i<=n;i++)add(i,i-1,0);  //代表s[i-1]-s[i]<=0
    54         for(int i=1;i<=ml;i++){
    55             int u,v,c;scanf("%d%d%d",&u,&v,&c);
    56             add(u,v,c);     //v-u<=c
    57         }
    58         for(int i=1;i<=md;i++){
    59             int u,v,c;scanf("%d%d%d",&u,&v,&c);
    60             add(v,u,-c);   //u-v<=-c,即v-u>=c
    61         }
    62         //利用题目条件,整合成三个差分约束条件,利用这几个条件建图,然后跑一遍最短路
    63         printf("%d
    ",spfa(1));
    64     }
    65 }

    2018-10-11

  • 相关阅读:
    GO 文档笔记
    GO 切片实力踩坑
    关于接口设计的一些反思
    Jenkins 发布.net core 程序,服务端无法下载nuget包的解决方法 error NU1102: 找不到版本为 (>= 3.1.6) 的包
    RabbitMQ 基础概念进阶
    RabbitMQ 入门之基础概念
    Object.entries()使用
    shadow的属性值介绍
    行内元素的特别之处
    margin的特别之处
  • 原文地址:https://www.cnblogs.com/00isok/p/9773338.html
Copyright © 2011-2022 走看看