Codeforces Round #625 (Div. 2) D. Navigation System /詳解

D. Navigation System
time limit per test2 seconds
memory limit per test512 megabytes
inputstandard input
outputstandard output
The map of Bertown can be represented as a set of n intersections, numbered from 1 to n and connected by m one-way roads. It is possible to move along the roads from any intersection to any other intersection. The length of some path from one intersection to another is the number of roads that one has to traverse along the path. The shortest path from one intersection v to another intersection u is the path that starts in v, ends in u and has the minimum length among all such paths.

Polycarp lives near the intersection s and works in a building near the intersection t. Every day he gets from s to t by car. Today he has chosen the following path to his workplace: p1, p2, …, pk, where p1=s, pk=t, and all other elements of this sequence are the intermediate intersections, listed in the order Polycarp arrived at them. Polycarp never arrived at the same intersection twice, so all elements of this sequence are pairwise distinct. Note that you know Polycarp’s path beforehand (it is fixed), and it is not necessarily one of the shortest paths from s to t.

Polycarp’s car has a complex navigation system installed in it. Let’s describe how it works. When Polycarp starts his journey at the intersection s, the system chooses some shortest path from s to t and shows it to Polycarp. Let’s denote the next intersection in the chosen path as v. If Polycarp chooses to drive along the road from s to v, then the navigator shows him the same shortest path (obviously, starting from v as soon as he arrives at this intersection). However, if Polycarp chooses to drive to another intersection w instead, the navigator rebuilds the path: as soon as Polycarp arrives at w, the navigation system chooses some shortest path from w to t and shows it to Polycarp. The same process continues until Polycarp arrives at t: if Polycarp moves along the road recommended by the system, it maintains the shortest path it has already built; but if Polycarp chooses some other path, the system rebuilds the path by the same rules.

Here is an example. Suppose the map of Bertown looks as follows, and Polycarp drives along the path [1,2,3,4] (s=1, t=4):

Check the picture by the link http://tk.codeforces.com/a.png

When Polycarp starts at 1, the system chooses some shortest path from 1 to 4. There is only one such path, it is [1,5,4];
Polycarp chooses to drive to 2, which is not along the path chosen by the system. When Polycarp arrives at 2, the navigator rebuilds the path by choosing some shortest path from 2 to 4, for example, [2,6,4] (note that it could choose [2,3,4]);
Polycarp chooses to drive to 3, which is not along the path chosen by the system. When Polycarp arrives at 3, the navigator rebuilds the path by choosing the only shortest path from 3 to 4, which is [3,4];
Polycarp arrives at 4 along the road chosen by the navigator, so the system does not have to rebuild anything.
Overall, we get 2 rebuilds in this scenario. Note that if the system chose [2,3,4] instead of [2,6,4] during the second step, there would be only 1 rebuild (since Polycarp goes along the path, so the system maintains the path [3,4] during the third step).

The example shows us that the number of rebuilds can differ even if the map of Bertown and the path chosen by Polycarp stays the same. Given this information (the map and Polycarp’s path), can you determine the minimum and the maximum number of rebuilds that could have happened during the journey?

Input
The first line contains two integers n and m (2≤n≤m≤2⋅105) — the number of intersections and one-way roads in Bertown, respectively.

Then m lines follow, each describing a road. Each line contains two integers u and v (1≤u,v≤n, u≠v) denoting a road from intersection u to intersection v. All roads in Bertown are pairwise distinct, which means that each ordered pair (u,v) appears at most once in these m lines (but if there is a road (u,v), the road (v,u) can also appear).

The following line contains one integer k (2≤k≤n) — the number of intersections in Polycarp’s path from home to his workplace.

The last line contains k integers p1, p2, …, pk (1≤pi≤n, all these integers are pairwise distinct) — the intersections along Polycarp’s path in the order he arrived at them. p1 is the intersection where Polycarp lives (s=p1), and pk is the intersection where Polycarp’s workplace is situated (t=pk). It is guaranteed that for every i∈[1,k−1] the road from pi to pi+1 exists, so the path goes along the roads of Bertown.

Output
Print two integers: the minimum and the maximum number of rebuilds that could have happened during the journey.

Examples
inputCopy
6 9
1 5
5 4
1 2
2 3
3 4
4 1
2 6
6 4
4 2
4
1 2 3 4
outputCopy
1 2
inputCopy
7 7
1 2
2 3
3 4
4 5
5 6
6 7
7 1
7
1 2 3 4 5 6 7
outputCopy
0 0
inputCopy
8 13
8 7
8 6
7 5
7 4
6 5
6 4
5 3
5 2
4 3
4 2
3 1
2 1
1 8
5
8 7 5 2 1
outputCopy
0 3

題意:
簡單說一下題意,就是題目給你一個有向圖,然後再給你一條路徑<u,v>,每次最短路的路徑變化的話會重新導航,讓你求出在<u,v>這條路徑上重新導航次數的最小值和最大值。

思路:

  1. 很明顯,最短路的路徑變化有兩種情況:
    ① u->v 的時候 距離終點的距離沒有-1
    (比如說u距離終點3,那麼v距離終點的距離應該爲2,否則就會重新導航)
    ② u->v 的時候 距離終點的距離-1 但是有其他最短路徑的選擇
    (比如說u->v->終點和u->k>終點,那麼導航就會由第二條變成第一條)
  2. 所以只要反向建圖,求出終點到其他點的最短路,然後再一一判斷即可。

代碼:

#include<bits/stdc++.h>
#include<string>
#include<cstring>
#include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
#define IOS ios::sync_with_stdio(false);cin.tie(0)
#define ll long long
//#define ll unsigned long long
#define inf 0x3f3f3f3f
#define mod 1000000007
#define eps 1e-6
#define PI acos(-1)
#define mysetit multiset<ll>::iterator
#define mymsetit multiset<ll>::iterator
#define mymapit map<ll,ll>::iterator
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define lowbit(x) (x&(-x))
#define mp make_pair
#define pb push_back
#define si size()
#define E exp(1.0)
#define fixed cout.setf(ios::fixed)
#define fixeds(x) setprecision(x)
using namespace std;
inline ll read(){ll s=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;}void put1(){ puts("Yes") ;}void put2(){ puts("No") ;}
void debug(){printf("我在這裏\n");}
void put3(){ puts("-1"); }ll qpf(ll a, ll b, ll p)
{ll ret = 0;while(b){if(b & 1) ret = (ret + a) % p;
a = (a + a) % p;b >>= 1;}return ret % p ;}
ll qp(ll a, ll n, ll p)
{ll ret = 1;while(n){if(n & 1) ret = qpf(ret, a, p);a = qpf(a, a, p);
n >>= 1;}return ret % p ;}
//θ=acos(L/2R);

const int manx=2e5+5;

vector<ll>g[manx],G[manx];
ll a[manx],d[manx],vis[manx];
ll n,m,p;
void dij(){
    for(int i=1;i<=n;i++) vis[i]=0,d[i]=1e9;
    priority_queue<pair<ll,ll> >q;
    q.push(mp(0,a[p]));
    d[a[p]]=0;
    while(q.size()){
        ll u=q.top().se; q.pop();
        if(vis[u]) continue;
        vis[u]=1;
        for(int i=0;i<G[u].si;i++){
            ll v=G[u][i];
           // cout<<u<<" "<<v<<" "<<d[u]<<"-"<<d[v]<<endl;
            if(d[v]>d[u]+1){
                d[v]=d[u]+1;
                q.push(mp(-d[v],v));
            }
        }
    }
}
int main(){
    n=read(),m=read();
    for(int i=1;i<=m;i++){
        ll u=read(),v=read();
        g[u].pb(v);
        G[v].pb(u);
    }
    p=read();
    for(int i=1;i<=p;i++) a[i]=read();
    dij();
    ll ans1=0,ans2=0;
   /* for(int i=1;i<=n;i++)
        cout<<d[i]<<endl;*/
    for(int i=1;i<p;i++){
        ll u=a[i],v=a[i+1];
        if(d[u]!=d[v]+1) ++ans1,++ans2;
        else{
            for(int j=0;j<g[u].si;j++){
                ll x=g[u][j];
                if(d[x]==d[u]-1&&x!=v){
                    ans2++;
                    break;
                }
            }
        }
    }
    printf("%lld %lld",ans1,ans2);
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章