• POJ 3169 Layout (spfa+差分约束)


    题目链接:http://poj.org/problem?id=3169

    题目大意:n头牛,按编号1~n从左往右排列,可以多头牛站在同一个点,给出ml行条件,每行三个数a b c表示dis[b]-dis[a]<=c,接下来有md行条件,每行三个数a b c,表示dis[b]-dis[a]>=c。求出出第一头牛和第n头牛的最大可能距离。若不可能把所有牛排成一排即条件有矛盾,则输出“-1”,若第一头牛和第n头牛的距离可以无限大,则输出“-2”。

    解题思路:第二道差分约束的题目。根据题目给出的三个约束条件:

         ①dis[B]-dis[A]<=C

         ②dis[B]-dis[A]>=C → dis[A]-dis[B]<=-C

         ③dis[A]-dis[B]<=0

    建图,然后同样的,因为要使距离尽可能大,所以if(dis[i]-dis[k]>cost[k][i])   dis[i]=dis[k]+cost[k][i]。

    当出现负环,则说明该图矛盾,输出“-1”,当dis[n]==INF说明1和n之间距离可以无穷大,输出“-2”,其他时候输出dis[n]-dis[1]。

    代码:

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<algorithm>
     5 #include<queue>
     6 using namespace std;
     7 const int N=1e3+5;
     8 const int INF=0x3f3f3f3f;
     9 const int MAXN=3e4+5;
    10 
    11 struct node{
    12     int to,w,next;
    13 }edge[MAXN];
    14 
    15 int n,idx;
    16 int head[N],dis[N],qcnt[N];
    17 bool vis[N];
    18 
    19 void init(){
    20     idx=1;
    21     memset(head,-1,sizeof(head));
    22 }
    23 
    24 void addedge(int u,int v,int w){
    25     edge[idx].w=w;
    26     edge[idx].to=v;
    27     edge[idx].next=head[u];
    28     head[u]=idx;
    29     idx++;
    30 }
    31 
    32 bool spfa(int s) {
    33     memset(dis,0x3f,sizeof(dis));
    34     dis[s]=0;
    35     queue<int>q;
    36     q.push(s);
    37     while(!q.empty()){
    38         int k=q.front();
    39         q.pop();
    40         vis[k]=false;
    41         for(int i=head[k];i!=-1;i=edge[i].next){
    42             node t=edge[i];
    43             if(dis[k]+t.w<dis[t.to]){
    44                 dis[t.to]=dis[k]+t.w;
    45                 if(!vis[t.to]){
    46                     q.push(t.to);
    47                     qcnt[t.to]++;
    48                     if(qcnt[t.to]>=n)
    49                         return false;
    50                     vis[t.to]=true;
    51                 }
    52             }
    53         }
    54     }
    55     return true;
    56 }
    57 
    58 int main(){
    59     init();
    60     int ml,md;
    61     scanf("%d%d%d",&n,&ml,&md);
    62     int a,b,c;
    63     for(int i=1;i<=ml;i++){
    64         scanf("%d%d%d",&a,&b,&c);
    65         addedge(a,b,c);            //b-a<=c 
    66     }
    67     for(int i=1;i<=md;i++){
    68         scanf("%d%d%d",&a,&b,&c);
    69         addedge(b,a,-c);        //b-a>=c → a-b<=-c都改成小于的形式 
    70     }
    71     for(int i=1;i<=n-1;i++){
    72         addedge(i+1,i,0);        //默认的dis[i+1]-dis[i]>=0
    73     }
    74     if(!spfa(1))
    75         puts("-1");
    76     else if(dis[n]==INF)
    77         puts("-2");
    78     else
    79         printf("%d
    ",dis[n]-dis[1]);
    80     return 0;
    81 }

         

  • 相关阅读:
    struts2学习笔记(二)
    struts2学习问题(一)
    struts2学习(一)
    给 ecplise 配置struts2配置环境
    Servlet的生命周期
    奇数位丢弃
    快速排序和归并排序(C语言)
    学习正则表达式及c#应用
    C#string与stringBuilder的区别
    c#之字符串函数
  • 原文地址:https://www.cnblogs.com/fu3638/p/7891117.html
Copyright © 2020-2023  润新知