Codeforces Round #625 (Div. 2, based on Technocup 2020 Final Round) D

题意:

有一个n个点m条边的有向图。给出一条其中路径经过k个点(k个不重复的点)

起点是s,终点是t。在这个路径上的每个点时,导航系统都会给出这个点到t的其中一条最短路;

如果这条最短路的下一个点 与 给出的路径下一个点不一样需要修改成到下一个点的位置,求最少的修改次数和最多的修改次数。

样例
6 9(6个点,9条边) 1 5 5 4 1 2 2 3 3 4 4 1 2 6 6 4 4 2 4(k个点,其中之一的路径) 1 2 3 4
输出
1 2


因为1-4的最短路是1-5-4,所以1-2修改,因为2-4的最短路有两条系统可能给2-3-4或者2-6-4,所以最小修改是1,最大修改是2

思路:
因为需要要k个点到t最短路(有向图),所以用bfs跑t到所有点的最短距离;
这些点(假设x)是否存在t到x点最短路径不同情况。如果有不同情况(如同样例2-4有两个可能)最大修改++;
如果存在k个点之中相邻的两个不是最短路连接的(如同样例5-1,而k个点之中时2-1),那么最大和最小修改都要++。

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define ll long long
  4 #define il inline
  5 #define it register int
  6 #define inf 0x3f3f3f3f
  7 #define lowbit(x) (x)&(-x)
  8 #define mem(a,b) memset(a,b,sizeof(a))
  9 #define mod 998244353
 10 const int maxn=2e5+10;
 11 struct node{
 12     int v,next;
 13 }a[maxn];
 14 vector<int>pan[maxn];
 15 struct node1{
 16     int x,bu;
 17     node1(){}
 18     node1(int xx,int buu):x(xx),bu(buu){}
 19     friend bool operator<(const node1 a,const node1 b){
 20         if(a.bu==b.bu){return a.x>b.x;}
 21         return a.bu>b.bu;
 22     }
 23 };
 24 int head[maxn],cnt,n,m,k,minnge,minbu,b[maxn],f,bu[maxn],ci[maxn];
 25 il void add(int v,int w){
 26     a[cnt].v=w;a[cnt].next=head[v];
 27     head[v]=cnt++;
 28 }
 29 il void bfs(int u,int buu){
 30     bu[u]=0;
 31     priority_queue<node1>q;
 32     q.push(node1(u,buu));
 33     while(!q.empty()){
 34         node1 tt=q.top();q.pop();
 35         int w=tt.x,bu2=tt.bu+1;
 36         for(it i=head[w];~i;i=a[i].next){
 37             int v=a[i].v;
 38             if(bu[v]==-1){
 39                 ci[v]++;bu[v]=bu2;pan[v].push_back(w);q.push(node1(v,bu2));
 40             }
 41             else if(bu[v]==bu2){
 42                 ci[v]++;pan[v].push_back(w);
 43             }
 44         }
 45     }
 46 }
 47 il bool pand(int u,int v){
 48     for(auto &i:pan[u]){
 49         if(i==v){return true;}
 50     }
 51     return false;
 52 }
 53 int main(){
 54     mem(head,-1);mem(bu,-1);
 55     scanf("%d%d",&n,&m);
 56     for(it i=0;i<m;i++){int v,w;
 57         scanf("%d%d",&v,&w);
 58         add(w,v);
 59     }
 60     scanf("%d",&k);
 61     int ma=0,mi=0;
 62     for(it i=0;i<k;i++){
 63         scanf("%d",&b[i]);
 64     }
 65     bfs(b[k-1],1);
 66     for(it i=0;i<k-1;i++){
 67         if(!pand(b[i],b[i+1])){
 68             mi++,ma++;
 69         }
 70         else{
 71             if(ci[b[i]]>1){ma++;}
 72         }
 73     }
 74     printf("%d %d\n",mi,ma);
 75     return 0;
 76 }
 77 /*
 78 20 50
 79 2 3
 80 18 10
 81 11 6
 82 11 1
 83 18 17
 84 18 7
 85 15 20
 86 6 11
 87 11 2
 88 8 2
 89 14 2
 90 20 1
 91 1 19
 92 17 2
 93 5 17
 94 15 17
 95 19 12
 96 16 9
 97 12 4
 98 19 2
 99 2 19
100 14 3
101 6 5
102 20 19
103 2 16
104 1 12
105 2 12
106 9 2
107 13 18
108 2 13
109 10 4
110 12 8
111 12 3
112 17 5
113 18 12
114 18 11
115 2 17
116 6 20
117 19 20
118 7 9
119 3 2
120 19 15
121 10 20
122 13 12
123 4 3
124 18 15
125 13 9
126 2 11
127 19 14
128 16 11
129 8
130 18 10 4 3 2 19 12 8
131 */
View Code

猜你喜欢

转载自www.cnblogs.com/luoyugongxi/p/12395902.html