zoukankan      html  css  js  c++  java
  • bzoj 4283 魔法少女伊莉雅

    题目大意

      给定一个 $n$ 个点 $m$ 条边的带正权无向图。要求找一条路径满足:

      它是一条简单路径

      它是一条严格次短路

      对于任何一条可能存在于最短路上的边,不能包含它的反向边。

      不存在这条路径输出 - 1。

    题解

      良心的最短路性质题,涵盖了大部分最短路径树和最短路径图上的常用性质。

      然后开始讲正题。

    最短路径图的基本性质

      将 $dleft (u, v ight)$ 记为点 $u$ 到点 $v$ 的最短路的长度。
      记 $d_{s}left (x ight ) = dleft (s, x ight ), d_{t}left (x ight ) = dleft (x, t ight )$。

      最短路径图是 $s$ 到 $t$ 的所有最短路径的并集。

      举个例子有助于说明:

      

      左边为原图,右边为最短路径图。

      注意 最短路径图是一个有向图。

      这里将原图记为 $G = (V, E)$,最短路径图记为 $G* = (V*, E*)$。

    最短路径图的基本性质 I(定义 1.1)

      对于任意 $e in E*$,若 $e = (u, v)$,那么 $d_{s}(u) + w (e) + d_{t}(v) = d (s, t)$。

      显然最短路径图一定是一个 DAG。

    最短路径图的基本性质 II(定理 1.1)

      对于任意 $x in V*$,那么有 $d_{s}(x) + d_{t}(x) = d (s, t)$。

      证明 如果 $s = x$,那么结论显然成立。

      现在考虑 $s eq x$ 的情况。暂时记 $L = d (s, t)$

      由最短路径图的定义可知 $d_{s}(x) geqslant L - d_{t}(x)$。因为 $x$ 不是起点,所以必然存在一个前驱 $x'$。

      根据基本性质 I 有 $d_{s}(x') + w (x', x) + d_{t}(x) = L$。由 $d_{s}(x)$ 的定义可知 $d_{s}(x) leqslant d_{s}(x') + w (x, x') = L - d_{t}(x)$。

      所以 $d_{s}(x) = L - d_{t}(x)$。

      因此定理得证。

    最短路径图的基本性质 III(推论 1.2)

      对于 $e = (x, y) in E*$,那么有 $d_{s}(x) + w (x, y) = d_{s}(y)$。

      证明 根据定理 1.1 有 $d_{s}(y) = d (s, t) - d_{t}(y)$。根据定义 1.1 有 $d_{s}(x) + w (x, y) = d (s, t) - d_{t}(y)$。然后定理得证。

    最短路径图的基本性质 IV(推论 1.3)

      如果最短路径图中存在一条 $x$ 到 $y$ 的简单路径,那么 $d_{s}(x) + l (P*(x, y)) + d_{t}(y) = L$。其中 P*(x, y) 表示一条在 $G*$ 上的路径,l (P*(x, y)) 表示这条路径的长度。

      重复使用推论 1.2 可以得到 $d_{s}(x) + l (P*(x, y)) = d_{s}(y)$。然后根据定理 1.1 易证。详细证明留给读者。

    最短路径图的基本性质 V(推论 1.4)

      最短路径图中一条 $x$ 到 $y$ 的简单路径,对应原图中一条 $x$ 到 $y$ 的最短路。

      有了推论 1.3 就可以使用反证法。详细证明留给读者。同时可以推出上面的 $ l (P*(x, y)) = d (x, y)$。

    定理 1.5

      若 $x, y in V*$,且满足 $x eq y, d_{s}(x) leqslant d_{x}(y)$,那么在 $G*$ 中 $s$ 到 $x$ 的最短路与 $y$ 到 $t$ 的最短路不相交。

      证明 根据最短路径图的定义(定义 1.1)可知,$s$ 到 $x$ 的过程中 $d_{s}(x')$ 递增,$y$ 到 $t$ 的过程中 $d_{s}(y')$ 递增。又因为 $x eq y, d_{s}(x) leqslant d_{x}(y)$,所以它们不相交。

    定理 2

      然后来讲一些约定吧。

      正向边:对于一条有向边 $(u, v)$,它在 $E*$ 中,那么我们称它为一条正向边。

      反向边:对于一条有向边 $(u, v)$,如果 $(v, u) in E*$,那么我们称它为一条反向边。

      内部边:正向边和反向边统称为内部边。

      外部边:在 $E$ 中,但不属于 $E*$ 的边。

      现在来明确一下约定路径的符号。

      $P (u, v)$,表示一条 $u$ 到 $v$ 的路径。

      $P*(u, v)$,表示一条在 $G*$ 中 $u$ 到 $v$ 的路径。

      $P (x, y) + Q (y, z)$,表示一条沿着路径 $P$ 从 $x$ 走到 $y$ 的,然后沿着 $Q$,从 $y$ 走到 $z$ 的路径。

      $P^{-1}(x, y)$,表示沿着路径 $P$ 的反向边(不是上面的定义的反向边),从 $y$ 到 $x$ 的一条路径。

      $P^{0}(x', y')$,路径 $P$ 上,一条 $x'$ 到 $y'$ 的子路径。

      $l (P)$,表示路径 $P$ 的长度。

      设所求路径为 $S$。

      外部路径:起点和终点在 $G*$ 中,经过的变都是外部边的一条简单路径。称起点是这条路径的拐出点,终点是这条路径的回归点。

    定理 2.1

      路径 $S$ 中存在至少 1 条外部路径。

      证明 如果不包含外部路径,那么路径 $S$ 中的边都是正向边(因为不能走反向边)。由于 $G*$ 是一个 DAG,所以 $l (S) = d (s, t)$,不符合题目要求。

    定理 2.2

      路径 $S$ 的包含一条外部路径的拐出点为 $x$,回归点为 $y$,那么有 $d_{s}(x) leqslant d_{s}(y)$。

      证明:

        假设结论不成立,那么有 $d_{s}(x) > d_{s}(y)$。

        设 $S = P (s, x) + Q (x, y) + R (y, t)$。那么令 $U = P*(s, y) + Q^{-1}(x, y) + R*(x, t)$。因为路径 $Q$ 是一条简单路径,P * 和 R * 都是由正向边组成,根据定理 1..5 可得 P * 与 R * 不相交。所以 $U$ 是一条简单路径。

        又因为 $U$ 包含了至少一条外部边,所以它不是最短路。因此是一条满足题目要求的路径。

        又因为 $P*(s, y) < P*(s, x) leqslant P (s, x), R*(x, t) < R*(y, t) leqslant R (y, t), Q (x, y) = Q^{-1}(x, y)$,所以 $l (U) < l (S)$。

        与 $S$ 的最优性矛盾。

    定理 2.3

      路径 $S$ 恰好包含一条外部路径。

    证明:

      假设包含的外部路径数目不是一条。

      如果不包含外部路径,显然矛盾。

      如果包含超过一条外部路径,设 $S = P*(s, x) + Q (x, y) + R (y, t)$,令 $U = P*(s, x) + Q (x, y) + R*(y, t)$,其中 $Q (x, y)$ 是一条外部路径。

      根据定理 1.5 易证 $U$ 是一条简单路径,根据最短路径图的定义有 $R*(y, t) < R (y, t)$,因此 $l (U) < l (S)$,与 $S$ 的最优性矛盾。

    最短路径树的性质

      约定 $S$ 的拐出点为 $S$ 包含的外部路径的拐出点,它的回归点为它包含的外部路径的回归点。

    定义 3.1

      定义一棵以 $p$ 为根的最短路径树 $T_{p} = (V, E_{T})$ 是原图中以 $p$ 为根的一棵有向路径生成树。其中一条边 $e (v, u)$ 满足 $d (u, p) + w (e) = d (v, p)$。

      由于下面只会用到 $T_{t}$,因此,以下可能会直接将它简记 $T$。

    注意

      这里的最短路径树是一个有向图。
      所有有向边都指向根节点。
      一张无向图的最短路径图唯一,但指定点的最短路径生成树可能不唯一。
      然后再来定义定义子树。

    定义 3.2

      在以 $p$ 为根的最短路径生成树中:

        点 $x$ 的子树,在 $T_{p}$ 点 $x$ 断掉点 $x$ 的唯一一条出边后,剩下的以 $x$ 为根的树是点 $x$ 的子树。记为 $T_{p}(x)$。

        点 $x$ 的真子树,点 $x$ 的真子树是 $T_{p}(x)$ 的一个子图。在 $T_{p}(x)$ 中,存在于点 $x$ 的真子树的点,当且仅当它到 $x$ 的路径上不经过除了 $x$ 以外的任何属于 $G*$ 的点。也就是说一个     不是 $x$ 的点,但属于 $G*$,一定不存在于 $x$ 的真子树中。记为 $T*_{p}(x)$。

      真子树的定义可能不是很好理解(再加上我语文不好),那么来举个栗子:

     

      在第三幅图之后,边权都被省略。在第四幅图和第五幅图中间橙色点标出的是在 $G*$ 中的点。

      下面有一个关于真子树的很基本的性质。

    定理 3.1

      对于任意 $x,y in G*$,都有 $T*(x)cap T*(y) = varnothing $。

      根据真子树的定义易证。

    接下来再来约定一个记号。

      $P_{T}(x, y)$,在树 $T_{t}$ 中,一条 $x$ 到 $y$ 的路径。

    最短路径树中的基本性质(定理 3.2)

      在最短路径树 $T_{t}$ 中,任意一个点 $x$ 到其祖先 $y$ 的一条简单路径,对应原图中一条 $x$ 到 $y$ 的最短路。

    证明

      证当 $y = t$ 时结论成立。

      考虑 $y eq t$ 的情况。

      仍然假设不是最短路。那么存在一条更优的路径的从 $x$ 到 $y$,然后到 $t$ 的路径。与 $T_{t}$ 的定义矛盾。

      因此定理得证。

      注意到如果将这条路径反向,可以对应 $y$ 到 $x$ 在原图中的一条最短路。

    定义 3.3

      在 $T$ 中,$x$ 的真祖先是在路径 $P_{T}(x, t)$ 中,离 $x$ 最近的一个在 $G*$ 中的点。将它记作 $prt (x)$。

      换一个说法就是沿着 $x$ 向它的出边走,直到遇到一个在 $G*$ 中的点。注意,它可能是 $x$ 也可能是 $t$。

      设 $S$ 的拐出点为 $x$,回归点为 $z$,显然 $x in T*(x), z in T*(z)$,根据定理 3.1,那么 $T*(x)$ 和 $T*(z)$ 不存在交集。所以在 $S$ 上必然存在一条外部边 $(w, w')$ 使得 $w in T*(x)$,且 $S^{0}(w', z)$ 中的各点均不在 $T*(x)$ 中。有一个很显然的事实是 $prt (w) = x$。

    定理 3.3

      $d_{s}(x) leqslant d_{s}(prt(w'))$。

    注意以下证明非常繁琐,请先喝口水再继续阅读。

    证明

      仍然假设结论不成立。那么有 $d_{s}(x) > d_{s}(prt (w'))$。所以 $d_{t}(x) < d_{t}(prt (w'))$。根据定理 2.2 有 $d_{s}(x) <= d_{s}(z)$,因此 $d_{s}(prt (w')) < d_{s}(z)$,所以 $prt (w') eq z$。根据定理 3.1,可知,必然存在一条边 $(y, y')$ 使得 $y in T*(prt (w'))$ 且 $S^{0}(y', z)$ 中的各点均不在 $T*(prt (w'))$。显然 $prt (w') = prt (y)$。

      令 $Q = P*(s, prt (w')), R = P_{T}(prt (w'), y), P = Q + R + S^{0}(y, t)$(见下图)。

     

      可以证明 $R$ 实际上是在 $T*(prt (w'))$ 中。假设路径上经过了其它的在 $G*$ 中的点,那么可知 $prt (y)$ 不等于 $prt (w')$,矛盾。

      因为 $d_{s}(prt (w'))< d_{s}(z)$,根据定理 1.5 可知 $Q$ 不与 $S^{0}(z, t)$ 相交,又因为 $R$ 在 $T*(prt (w'))$ 中,所以经过的边都是外部边,所以 $P$ 中的内部边不相交。又因为 $S^{0}(y'. z)$ 是一条外部的简单路径,且不在 $T*(prt (w'))$。所以路径 $P$ 中的外部边不相交。因此路径 $P$ 是一条简单路径。(注意:这里的相交指的是存在环,而不是边与边存在公共点。)

      又因为 $P$ 包含了至少一条外部边,所以 $P$ 是一条满足要求的路径(除了严格次短)。

      因为 $S$ 是所求路径,所以有:

        $l(S) leqslant l(P)$

        $l(S^{0}(s, x)) + l(S^{0}(x, y)) + l(S^{0}(y, t)) leqslant l(Q) + l(R) + l(S^{0}(y, t))$

        $l(S^{0}(s, x)) + l(S^{0}(x, y)) leqslant l(Q) + l(R)$

        $d_{s}(x) + l (S^{0}(x, y)) leqslant d_{s}(prt (w')) + l (R)$(推论 1.4)

      又因为 $prt (w') < d_{s}(x)$,所以 $l (S^{0}(x, y)) < l (R)$。

      令 $U = S^{0}(x, y)^{-1} + P*(x, t)$。那么有:

        $l(U) = l(S^{0}(x, y)^{-1}) + l(P*(x, y))\=l(S^{0}(x,y)) + d_{t}(x)\<l(R) + d_{t}(prt(w'))\=l(R^{-1}) + d_{t}(prt(w'))\=l(P_{t}(y,t))$

      但是 $U$ 经过了至少一条外部边,所以有 $l (U) > l (P_{T}(y, t)) = d_{t}(y)$。但是刚刚却推出了与之矛盾的式子。

      所以假设不成立,定理得证:$d_{s}(x) leqslant (prt (w'))$。

    定理 3.4

      必然存在一个满足所有条件的路径 S*,满足$S* = P_{T}(s, w) + (w, w') + P_{T}(w', t)$ 

      其中 $(w, w')$ 是定理 3.3 中涉及到的一条边。

    证明

      令 $Q = P_{T}(s, w), R = P_{T}(w', t)$,根据定理 3.1 易证 $S*$ 的外部边不相交,根据定理 3.3 和定理 1.5 易证 $S*$ 的内部边不会相交。又因为 $(w, w')$ 一定是一条外部边。所以 $S*$ 是一条简单路径但不是最短路径。

      因为 $S$ 中包含至少一条非树边,然后用反证法易证存在一个 $S*$ 是满足题目所有要求的路径(除非原问题不存在解)。

      于是定理 3.4 创造了无限可能。

    做法

      我们只需要枚举一条非内部边,非树边 $e (x, y)$,且满足 $prt (x) eq prt (y)$ 且 $d_s (prt (x)) leqslant d_s (prt (y))$,然后用 $d_{s}(x) + w (e) + d_{t}(y)$ 去更新答案即可。

      虽然证明很复杂,但是算法却异常简单。

    代码

     1 #include<bits/stdc++.h>
     2 #define LL long long
     3 #define pb push_back
     4 #define _(d) while(d(isdigit(ch=getchar())))
     5 using namespace std;
     6 int R(){
     7     int x;bool f=1;char ch;_(!)if(ch=='-')f=0;x=ch^48;
     8     _()x=(x<<3)+(x<<1)+(ch^48);return f?x:-x;}
     9 const int N=5e5+5;
    10 int n,m,head[N],cnt,flag[N<<1],fa[N],ans=2e9;
    11 struct edge{int fro,to,nex,w;}e[N<<1];
    12 void add(int s,int t,int w){e[++cnt]=(edge){s,t,head[s],w},head[s]=cnt;}
    13 struct node{
    14     int x,w;
    15     bool friend operator <(node a,node b){return a.w>b.w;}
    16 };priority_queue<node>q;
    17 int dis[2][N];
    18 void Dij(int s,int f){
    19     memset(dis[f],0x3f,sizeof dis[f]);
    20     dis[f][s]=0;
    21     q.push((node){s,0});
    22     while(!q.empty()){
    23         node now=q.top();q.pop();
    24         if(dis[f][now.x]!=now.w)continue;
    25         for(int k=head[now.x],v;k;k=e[k].nex)
    26             if(dis[f][now.x]+e[k].w<dis[f][v=e[k].to])
    27                 dis[f][v]=dis[f][now.x]+e[k].w,q.push((node){v,dis[f][v]});
    28     }
    29     return;
    30 }
    31 vector<int> g[N];
    32 void dfs(int u){
    33     for(int i=g[u].size()-1,v;~i;i--){
    34         if(dis[0][v=g[u][i]]+dis[1][v]!=dis[0][n])fa[v]=fa[u];
    35         else fa[v]=v;
    36         dfs(v);
    37     }
    38 }
    39 int main(){
    40     n=R(),m=R();
    41     for(int i=1,u,v,w;i<=m;i++)
    42         u=R(),v=R(),w=R(),add(u,v,w),add(v,u,w);
    43     Dij(1,0),Dij(n,1);
    44     for(int i=1;i<=n;i++)
    45         for(int k=head[i],v;k;k=e[k].nex)
    46             if(dis[1][i]==dis[1][v=e[k].to]+e[k].w){
    47                 flag[k]=1,g[v].pb(i);
    48                 break;
    49             }
    50     fa[n]=n,dfs(n);
    51     for(int k=1,u,v,w;k<=cnt;k++)
    52         if(!flag[k]&&dis[0][u=e[k].fro]<=dis[0][v=e[k].to]&&fa[u]!=fa[v]&&dis[0][u]+(w=e[k].w)+dis[1][v]!=dis[0][n])
    53             ans=min(ans,dis[0][u]+w+dis[1][v]);
    54     printf("%d
    ",ans);
    55     return 0;
    56 }
    View Code

    转载至:http://www.cnblogs.com/yyf0309/p/8563071.html

  • 相关阅读:
    Uva 10779 collector's problem
    poj 2728 最优比率树(最小生成树问题)
    LA 3126 二分图匹配 最小路径覆盖
    poj 1149 最大流构图
    Step By Step(Java XML篇)
    Step By Step(Java 输入输出篇)
    Step By Step(Java 集合篇)
    Step By Step(Java 线程篇)
    Step By Step(Java 反射篇)
    Step By Step(Java 国际化篇)
  • 原文地址:https://www.cnblogs.com/chmwt/p/10648549.html
Copyright © 2011-2022 走看看