• poj 3169 差分约束


    3169

    差分约束的是满足多组形如xi-yj<=bk{i,j<n k<m}不等式极值问题,可以转化为单源最短路来求。

    在最短路中 d[v]<=d[u]+w(u,v) 可以看出跟上面的不等式很像

    通常有两种一种是求满足所有不等式的最大值,还有是最小值。

    这篇博客可以参考一下

    分析:

    题目给出了两种不等式  d[u]+dl >=d[v]       d[u]+dd<=d[v]  要求的是最大值,也就是最短路

    对于d[u]+dl>=d[v] 建边(u,vdl) 

    对于d[u]+dd<=d[v] 建边(v,u,-dd)

    然后跑一边最短路就好了,注意是负权图

    如果有负环则无解,有点最短距离未更新为多解,否则为S->e的最短距离

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <set>
     5 #include <algorithm>
     6 #include <map>
     7 #include <queue>
     8 #include<vector>
     9 #define maxn 50010
    10 #define maxm 100010
    11 #define INF 0x3fffffff
    12 using namespace std;
    13 struct edge{
    14     int from,to,w;
    15     edge(){}
    16     edge(int _u,int _v,int _w){
    17         from=_u,to=_v,w=_w;
    18     }
    19 };
    20 edge G[maxm];
    21 int V,E;
    22 void addedge(int u,int v,int w){
    23     G[E++]=edge(u,v,w);
    24 }
    25 int d[maxn];
    26 int n,m;
    27 void bellman_ford(int s){
    28     V=n;
    29     for(int i=0;i<V;++i)d[i]=INF;
    30     d[s]=0;
    31     while(1){
    32         bool flag =false;
    33         for(int i=0;i<E;++i){
    34             edge e = G[i];
    35             if(d[e.from]!=INF&&d[e.to]>d[e.from]+e.w){
    36                 d[e.to] = d[e.from]+e.w;
    37                 flag = true;
    38             }
    39         }
    40         if(!flag)break;
    41     }
    42 }
    43 bool HaveNagativeLoop(){
    44     memset(d,0,sizeof(d));
    45     for(int i=0;i<V;++i){
    46         for(int j=0;j<E;++j){
    47             edge e = G[j];
    48             if(d[e.to]>d[e.from]+e.w){
    49                 d[e.to] = d[e.from]+e.w;
    50                 if(i==V-1)return true;
    51             }
    52         }
    53     }
    54     return false;
    55 }
    56 int ml,md;
    57 int main (){
    58     while(scanf("%d%d%d",&n,&ml,&md)!=EOF){
    59         int u,v,w;
    60         E=0;
    61         V=n;
    62         for(int i=0;i<n-1;++i){
    63             addedge(i+1,i,0);
    64         }
    65         for(int i=0;i<ml;++i){
    66             scanf("%d%d%d",&u,&v,&w);
    67             addedge(u-1,v-1,w);
    68         }
    69         for(int i=0;i<md;++i){
    70             scanf("%d%d%d",&u,&v,&w);
    71             addedge(v-1,u-1,-w);
    72         }
    73         if(HaveNagativeLoop()){printf("-1
    ");continue;}
    74         bellman_ford(0);
    75         if(d[n-1]==INF)printf("%d
    ",-2);
    76         else printf("%d
    ",d[n-1]);
    77     }
    78 }
    View Code
  • 相关阅读:
    PHP静态
    PHP批量删除
    PHP增删改查
    PHP数据访问
    PHP继承和多态
    PHP封装
    PHP字符串处理和正则表达式
    PHP数组
    PHP函数
    PHP基础
  • 原文地址:https://www.cnblogs.com/shuzy/p/3784056.html
Copyright © 2020-2023  润新知