5.6 每日一题题解

tokitsukaze and Event

涉及知识点:

  • 最短路/思维

solution:

  • (这个题乍一看没啥好的思路,我们把伤害都转化成两点之间的路径长度)
  • (问题转化成考察最短路的应用,如果不会写最短路建议先学习最短路)
  • (先求出发点s到所有点到的最短路,这个路径要求是白天模式的路径)
  • (然后再求终点t到所有点的最短路,这个路径要求是夜间模式的路径)
  • (把出发点到每个点的最短路存到数组dis1中,把终点到每个点的最短路存到数组dis2中)
  • (如果在第i个位置切换模式,那最短路径 = dis1[i] + dis2[i])
  • (那么答案其实就是Min(dis1[i] + dis2[i])(1<=i<=n))
  • (但是题目要求切换夜间模式的点不能小于难度!所以必须要从后往前遍历记录最小值)

std:

#include <bits/stdc++.h>
using namespace std;
#define  ll long long
const ll inf = 1e18;
const int maxx = 1e5+10;
int n,m;
ll dis1[maxx],dis2[maxx],a[maxx];

struct node{
    int to;
    ll w;
    friend bool operator <(node p1,node p2){
        return p1.w > p2.w;
    }//小优先
};
vector<node> v1[maxx];
vector<node> v2[maxx];
priority_queue<node> q;

void spfa(int s)
{
    fill(dis1+1,dis1+1+n,inf);
    dis1[s] = 0;
    while(!q.empty())
        q.pop();
    q.push(node{s,0});
    while(!q.empty())
    {
        node x = q.top();q.pop();
        int k = x.to;
        if(x.w > dis1[x.to])
            continue;
        for(int i=0;i<v1[k].size();i++){
            if(dis1[v1[k][i].to] > x.w + v1[k][i].w){
                dis1[v1[k][i].to] = x.w + v1[k][i].w;
                q.push(node{v1[k][i].to,dis1[v1[k][i].to]});
            }
        }
    }
}
void spfa2(int s)
{
    fill(dis2+1,dis2+1+n,inf);
    dis2[s] = 0;
    while(!q.empty())
        q.pop();
    q.push(node{s,0});
    while(!q.empty())
    {
        node x = q.top();q.pop();
        if(x.w > dis2[x.to])
            continue;
        int k = x.to;
        for(int i=0;i<v2[k].size();i++){
            if(dis2[v2[k][i].to] > x.w + v2[k][i].w){
                dis2[v2[k][i].to] = x.w + v2[k][i].w;
                q.push(node{v2[k][i].to,dis2[v2[k][i].to]});
            }
        }
    }
}

int main()
{
    cin>>n>>m;
    int x,y,l1,l2,t,s;
    for(int i=1;i<=m;i++){
        cin>>x>>y>>l1>>l2;
        v1[x].push_back({y,l1});
        v1[y].push_back({x,l1});
        v2[x].push_back({y,l2});
        v2[y].push_back({x,l2});
    }
    scanf("%d%d",&t,&s);
    spfa(t);spfa2(s);

    ll ans = inf;
    for(int i=n;i>=1;i--){
        ans = min(ans,dis1[i]+dis2[i]);
        a[i] = ans;
    }
    for(int i=1;i<=n;i++){
        printf("%lld
",a[i]);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/QFNU-ACM/p/12835385.html