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;
    }
    
    
  • 相关阅读:
    使用 Dockerfile 定制镜像
    UVA 10298 Power Strings 字符串的幂(KMP,最小循环节)
    UVA 11090 Going in Cycle!! 环平均权值(bellman-ford,spfa,二分)
    LeetCode Best Time to Buy and Sell Stock 买卖股票的最佳时机 (DP)
    LeetCode Number of Islands 岛的数量(DFS,BFS)
    LeetCode Triangle 三角形(最短路)
    LeetCode Swap Nodes in Pairs 交换结点对(单链表)
    LeetCode Find Minimum in Rotated Sorted Array 旋转序列找最小值(二分查找)
    HDU 5312 Sequence (规律题)
    LeetCode Letter Combinations of a Phone Number 电话号码组合
  • 原文地址:https://www.cnblogs.com/1024-xzx/p/12682980.html
Copyright © 2011-2022 走看看