zoukankan      html  css  js  c++  java
  • 【差分约束系统/SPFA】POJ3169-Layout

    【题目大意】

    n头牛从小到大排,它们之间某些距离不能大于一个值,某些距离不能小于一个值,求第一头牛和第N头牛之间距离的最大值。

    【思路】

    由题意可以得到以下不等式d[AL]+DL≥d[BL];d[BD]+(-DD)≥d[AD];d[i+1]+0≥d[i],显然是差分约束系统。即构造从AL到BL权值为DL的边,从BD到AD构造权值为-DD的负边,从i+1到i构造权值为0的边。最后求最短路径。安利一个证明(点我)。

    对于差分约束系统要注意的是,如果要求最大距离,用最短路径;求最小距离,用最长路径,要根据实际情况判断。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<queue>
     5 using namespace std;
     6 const int MAXN=10000+5;
     7 struct Rec
     8 {
     9     int ori,des,len;
    10 };
    11 int n,ml,md;
    12 int first[MAXN/10],next[MAXN*2+1000];
    13 Rec edge[MAXN*2+1000];
    14 int vis[MAXN/10],dis[MAXN/10],appear[MAXN/10];
    15 
    16 void init()
    17 {
    18     memset(first,-1,sizeof(first));
    19     scanf("%d%d%d",&n,&ml,&md);
    20     int j=-1;
    21     for (int i=0;i<ml;i++)
    22     {
    23         j++;
    24         scanf("%d%d%d",&edge[j].ori,&edge[j].des,&edge[j].len);
    25         edge[j].ori--;edge[j].des--;
    26         next[j]=first[edge[j].ori];
    27         first[edge[j].ori]=j;
    28     }
    29     for (int i=0;i<md;i++)
    30     {
    31         j++;
    32         scanf("%d%d%d",&edge[j].des,&edge[j].ori,&edge[j].len);
    33         edge[j].ori--;edge[j].des--;
    34         edge[j].len=0-edge[j].len;
    35         next[j]=first[edge[j].ori];
    36         first[edge[j].ori]=j;
    37     }
    38     for (int i=1;i<n;i++)
    39     {
    40         j++;
    41         edge[j].ori=i;edge[j].des=i-1;edge[j].len=0;
    42         next[j]=first[edge[j].ori];
    43         first[edge[j].ori]=j;
    44     }
    45 }
    46 
    47 void SPFA()
    48 {
    49     queue<int> que;
    50     memset(vis,0,sizeof(vis));
    51     memset(appear,0,sizeof(appear));
    52     for (int i=1;i<n;i++) dis[i]=0x7fffffff;
    53     dis[0]=0;
    54     que.push(0);
    55     vis[0]=1;
    56     appear[0]++;
    57     
    58     while (!que.empty())
    59     {
    60         int head=que.front();
    61         int k=first[head];
    62         while (k!=-1)
    63         {
    64             Rec e=edge[k];
    65             if (dis[e.des]>dis[e.ori]+e.len)
    66             {
    67                 dis[e.des]=dis[e.ori]+e.len;
    68                 if (!vis[e.des])
    69                 {
    70                     appear[e.des]++;
    71                     if (appear[e.des]>n)
    72                     {
    73                         cout<<-1<<endl;
    74                         return;
    75                     }
    76                     que.push(e.des);
    77                     vis[e.des]=1;
    78                 }
    79             }
    80             k=next[k];
    81         }
    82         vis[head]=0;
    83         que.pop();
    84     }
    85     if (dis[n-1]==0x7fffffff) cout<<-2<<endl; else cout<<dis[n-1]<<endl;
    86 }
    87 
    88 int main()
    89 {
    90     init();
    91     SPFA();
    92     system("pause");
    93     return 0; 
    94 } 
  • 相关阅读:
    FastDFS+Nginx部署详细教程
    简单的区别记录
    linux搜索命令之find和grep
    [转载]redis持久化的两种操作RDB和AOF
    多线程的一点点整理
    利用spring-mail模块发送带附件邮件dome
    java集合类总结
    微信支付 遇到的问题
    dubbo监控工具
    Maven配置dubbo环境简单例子
  • 原文地址:https://www.cnblogs.com/iiyiyi/p/4708156.html
Copyright © 2011-2022 走看看