zoukankan      html  css  js  c++  java
  • 最短路变短了【最短路】

    题意:

    题目链接
    题解链接

    分析:

      首先,在原图上以点 (1) 为起点跑一遍最短路,处理出 (dis1[i])
      然后,把所有边反向以点 (n) 为起点跑一遍最短路,处理出 (dis2[i])
      当把第 (i) 条边反向后,假设该边的为 (u o v),边权为 (c)。修改之后的图与原图相比,可能替代原来最短路变成新最短路的路径只有可能是 (1 o v o u o n)
    因此,需要判断该条路径和原最短路的关系。
    (dis1[v]+dis2[u]+c<dis1[n]) 时,表示最短路变短,否则没有。
    证明:
    对于该式子:

    [dis1[v]+dis2[u]+c ]

      (dis2[u]) 为反向图时求的最短路,把边反向时对其值没有影响。(c) 的值也不变。但边 (u o v) 反转后,可能会对 (dis1[v]) 产生影响,只需要对 (dis1[v]) 进行讨论。
    (dis1[v]) 并没有经过边 (u o v) 时,(dis1[v]) 并没有发生改变,可以直接用于判断。
    (dis1[v]) 经过了边 (u o v) 时,那么当该边反向后,(dis1[v]^{'}geq dis1[v]),如果仍用 (dis1[v]) 来判断的话,这条新的路径的长度会比原来路径 (1 o u o v o n) 要多 (c),因此必然不可能,所以用 (dis1[v]) 仍然可以判断。

    代码:

    #include <bits/stdc++.h>
    #define pb push_back
    using namespace std;
    typedef long long ll;
    typedef pair<ll,int>P;
    const ll inf=1e16;
    const int N=1e5+5;
    struct edge
    {
        int u,v;
        ll w;
    }e[N<<1];
    vector<P>G[2][N];
    priority_queue<P,vector<P>,greater<P> >que;
    ll dis[2][N];
    void read(int &x)
    {
        x=0;
        int f=1;
        char ch=getchar();
        while(!isdigit(ch))
        {
            if(ch=='-')
                f=-1;
            ch=getchar();
        }
        while(isdigit(ch))
        {
            x=(x<<3)+(x<<1)+ch-'0';
            ch=getchar();
        }
        x*=f;
    }
    void dij(int s,int f,int n)
    {
        while(!que.empty())
            que.pop();
        que.push(make_pair(0,s));
        for(int i=1;i<=n;i++)
            dis[f][i]=inf;
        dis[f][s]=0;
        while(!que.empty())
        {
            P now=que.top();
            que.pop();
            if(dis[f][now.second]<now.first)
                continue;
            for(int i=0;i<G[f][now.second].size();i++)
            {
                P tmp=G[f][now.second][i];
                if(dis[f][tmp.second]>dis[f][now.second]+tmp.first)
                {
                    dis[f][tmp.second]=dis[f][now.second]+tmp.first;
                    que.push(make_pair(dis[f][tmp.second],tmp.second));
                }
            }
        }
    }
    int main()
    {
        int n,m,u,v,c,q,d;
        read(n),read(m);
        for(int i=1;i<=m;i++)
        {
            read(u),read(v),read(c);
            G[0][u].pb(make_pair(c,v));
            G[1][v].pb(make_pair(c,u));
            e[i].u=u;
            e[i].v=v;
            e[i].w=c;
        }
        dij(1,0,n);
        dij(n,1,n);
        read(q);
        while(q--)
        {
            read(d);
            if(dis[0][e[d].v]+dis[1][e[d].u]+e[d].w<dis[0][n])
                printf("YES
    ");
            else
                printf("NO
    ");
        }
        return 0;
    }
    
    
  • 相关阅读:
    NFC Basics(基本NFC)——翻译自developer.android.com
    【LeetCode】Sort Colors 解题报告
    发送手机物理标识请求
    Java编程介绍
    emacs 中使用git diff命令行
    OpenJudge百炼习题解答(C++)--题4074:积水量
    编程之美2.9 斐波那契数列
    Application Architecture Determines Application Performance
    程序包javax.servlet.annotation不存在
    mysql 严格模式 Strict Mode说明
  • 原文地址:https://www.cnblogs.com/1024-xzx/p/12682980.html
Copyright © 2011-2022 走看看