D. Navigation System

题目链接:http://codeforces.com/contest/1321/problem/D

题目大意:

给你一张有向图,再给你一个路径,在路径的每一步上都维护最短路,如果不是按照最短路走就更新最短路,输出最小或最大更新次数(有最小或最大是因为最短路不唯一)。

想法:

反向连边跑dij,记录最短路以及最短路的条数

然而记录最短路条数需要重新正向连一次边

#include <algorithm>
#include <string>
#include <string.h>
#include <vector>
#include <map>
#include <stack>
#include <set>
#include <queue>
#include <math.h>
#include <cstdio>
#include <iomanip>
#include <time.h>
#include <bitset>
#include <cmath>
#include <sstream>
#include <iostream>

#define LL long long
#define INF 0x3f3f3f3f
#define ls nod<<1
#define rs (nod<<1)+1
#define pii pair<int,int>

const double eps = 1e-10;
const int maxn = 2e5 + 10;;
const LL mod = 1e9 + 7;

int sgn(double a){return a < -eps ? -1 : a < eps ? 0 : 1;}
using namespace std;

int head[maxn],head2[maxn];
int dist[maxn];
bool vis[maxn];
int cnt,cnt2;
int p[maxn],q[maxn];

struct Edge{
    int to,next;
}edge[maxn],e[maxn];

void init(){
    cnt = 0;
    cnt2 = 0;
    memset(head,-1, sizeof(head));
    memset(head2,-1, sizeof(head2));
    memset(vis,false, sizeof(vis));
    memset(dist,INF, sizeof(dist));
}

void add(int u,int v){
    edge[++cnt].to = v;
    edge[cnt].next = head[u];
    head[u] = cnt;
    int uu = v,vv = u;
    e[++cnt2].to = vv;
    e[cnt2].next = head2[uu];
    head2[uu] = cnt2;
}

void dijstra(int s)
{
    priority_queue<pii,vector<pii>,greater<pii> > q;
    dist[s] = 0;
    q.push({dist[s],s});
    while (!q.empty())
    {
        int now = q.top().second;
        q.pop();
        if (vis[now])
            continue;
        vis[now] = true;
        for (int i=head[now];i!=-1;i=edge[i].next)
        {
            int v = edge[i].to;
            if (dist[v]>dist[now]+1)
            {
                dist[v] = dist[now] + 1;
                q.push({dist[v],v});
            }
        }
    }
}

int main() {
    ios::sync_with_stdio(false);
    init();
    int n,m;
    cin >> n >> m;
    for (int i = 1;i <= m;i++) {
        int u,v;
        cin >> u >> v;
        add(v,u);
    }
    int k;
    cin >> k;
    for (int i = 1;i <= k;i++)
        cin >> p[i];
    dijstra(p[k]);
    for (int i = 1;i <= n;i++) {
        for (int j = head2[i];~j;j = e[j].next) {
            int v = e[j].to;
            if (dist[v]+1 == dist[i])
                q[i]++;
        }
    }
    int maxx = 0,minn = 0;
    for (int i = 1;i < k;i++) {
        if (dist[p[i]] != dist[p[i+1]]+1)
            maxx++,minn++;
        else if (q[p[i]] > 1)
            maxx++;
    }
    cout << minn << " " << maxx << endl;
    return 0;
}
原文地址:https://www.cnblogs.com/-Ackerman/p/12420119.html