B. Navigation System (thinking + reverse side construction shortest path / shortest path count)

https://codeforces.com/problemset/problem/1320/B


Ideas:

It depends on whether the next step of the current route is on the shortest path. If it is (shortest distance -1), find the same shortest distance path to the end point.

If not, it means that the route you took is not the shortest route, and the navigation is corrected once.

As for how to find the shortest path from multiple points to the end point, reverse mapping is the shortest path from the end point to each point, and the distance is the same.

Note; if there are multiple shortest paths, the navigation can only be selected at that point for planning. So when you finally modify the maximum value, you find one and break;

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=2e5+1000;
typedef long long LL;
typedef pair<LL,LL>P;///第一维代表距离,第二维代表点
inline LL read(){LL x=0,f=1;char ch=getchar();	while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;}
struct Edge{
    LL to,cost;
};
vector<Edge>g[maxn],z[maxn];
LL a[maxn];
LL dis[maxn];
bool vis[maxn];

void dijkstra(LL s){
    memset(dis,0x3f,sizeof(dis));
    memset(vis,0,sizeof(vis));
    LL st=s;
    dis[st]=0;
    priority_queue< P, vector<P>, greater<P> >que;
    que.push({dis[st],st});
    while(!que.empty()){
        P now=que.top();que.pop();
        LL u=now.second;
        if(vis[u]) continue;
        vis[u]=true;
        for(LL i=0;i<g[u].size();i++){
            Edge e=g[u][i];
            if(dis[e.to]>dis[u]+e.cost){
                dis[e.to]=dis[u]+e.cost;
                que.push({dis[e.to],e.to});
            }
        }
    }
}
int main(void)
{
  cin.tie(0);std::ios::sync_with_stdio(false);
  LL n,m;cin>>n>>m;
  for(LL i=1;i<=m;i++){
    LL u,v;cin>>u>>v;
    g[v].push_back({u,1LL});
    z[u].push_back({v,1LL});
  }
  LL k;cin>>k;
  for(LL i=1;i<=k;i++) cin>>a[i];
  dijkstra(a[k]);

  /*for(LL i=1;i<=n;i++){
    cout<<dis[i]<<" ";
  }
  cout<<"\n";*/
  LL minv=0;LL maxv=0;

  for(LL i=1;i<k;i++){
    LL u=a[i];LL v=a[i+1];
    if(dis[u]!=dis[v]+1) minv++,maxv++;
    else{
        for(LL j=0;j<z[u].size();j++){
            LL to=z[u][j].to;
            if(dis[to]+1==dis[u]&&to!=v){
                maxv++;
                break;
            }
        }
    }
  }
  cout<<minv<<" "<<maxv<<"\n";
return 0;
}

 

Guess you like

Origin blog.csdn.net/zstuyyyyccccbbbb/article/details/114897210