【noip2022–图论专项练习】题解
T1—base
题目描述
你来到Mars上开疆扩土。
Mars上一共有 n n n个城镇,从1到 n n n编号。Mars上还有 m m m条双向铁路,从1到 m m m编号。
你是一个疯狂的基建爱好者。除了铁路网络,你还有一个公路网络。对于每一对不同的城镇 x x x和 y y y, x x x和 y y y之间存在一条双向公路当且仅当它们之间没有铁路。从任意城镇出发,经过一条铁路/公路前往其他的城镇总是需要1小时。
一列火车和一辆公共汽车同时离开城镇1。火车只能沿铁路行驶,公共汽车只能沿公路行驶。它们都有相同的目的地,即城镇,并且在途中不做任何停留,但可以在城镇等待。
你正在为火车和公共汽车规划路线。火车/公共汽车可以多次经过任何公路/铁路。你需要考虑的最重要方面之一是安全:为了避免在道路口发生事故,火车和公共汽车不得同时到达同一个城镇(城镇 n n n除外)。
在这些限制条件下,你需要求出两辆车到达城镇 n n n所需的最少小时数,即使得公共汽车和火车到达时间的较大值最小。请注意,公共汽车和火车不必同时到达城镇 n n n。
输入格式
输入的第一行包含两个整数 n n n和 m m m,分别是城镇的数量和铁路的数量。
接下来的 m m m行中的每一行包含两个整数 u u u和 v v v,表示城镇和之间存在一条双向铁路( 1 ≤ u ≠ v ≤ n 1≤u≠v≤n 1≤u=v≤n)。 任何两个城镇之间最多有一条铁路。
输出格式
输出一个整数,表示答案。 如果至少有一辆车辆不可能到达城镇 n n n,则输出-1。
i n p u t input input
4 2
1 3
3 4
o u t p u t output output
2
20分做法:
暴力搜索两条路径。时间复杂度 O ( ( n ! ) 2 ) O((n!)^2) O((n!)2)。
40分做法:
最短路算法: d i s [ x ] [ y ] dis[x][y] dis[x][y]表示max{火车到达 x x x的时间,汽车到达 y y y的时间}的最小值。
时间复杂度 O ( n 4 ) O(n^4) O(n4)。
80分做法:
铁路或者公路其中之一包括 1 1 1到 n n n这条边。
假如铁路包括 1 1 1到 n n n这条边,那么火车可以在1小时内到达城镇 n n n。所以只需要求汽车沿着公路从 1 1 1到 n n n的最短路。
公路包括 1 1 1到 n n n这条边的情况也类似。
最短路可以用Floyd求,时间复杂度 O ( n 3 ) O(n^3) O(n3)。
100分做法:
延续80分的做法。边权都是 1 1 1,最短路可以用bfs求。
时间复杂度 O ( n 2 ) O(n^2) O(n2)。
#include<bits/stdc++.h>
using namespace std;
int n,m,u,v,i,d[5010],a[5010][5010];
int main(){
freopen("base.in", "r", stdin);
freopen("base.out", "w", stdout);
cin>>n>>m;
while(m--){
cin>>u>>v,a[u][v]=a[v][u]=1;}
queue<int>q;
q.push(1);
while(!q.empty()){
int x=q.front();q.pop();
if(x==n){
printf("%d",d[n]);return 0;}
for(i=2;i<=n;i++)if(!d[i]&&a[x][i]!=a[1][n])q.push(i),d[i]=d[x]+1;
}
cout<<-1;
return 0;
}
T2—matrix
题目描述
给定一个大小为 n × m n×m n×m的矩阵,最初用0填充。我们用 a i j a_ij aij表示矩阵第 i i i行第 j j j列中的元素。
如果矩阵中的两个元素相邻(上下左右四个方向),并且这两个元素相等,则它们是连接的。
你对这个矩阵中连通块的个数特别感兴趣。
给你 q q q个形为 x i , y i , c i ( 1 ≤ i ≤ q − 1 ) x_i,y_i,c_i(1≤i≤q-1) xi,yi,ci(1≤i≤q−1)的查询。 对于每个查询,你需要执行以下操作: 将元素 a x i y i a_ xi_yi axiyi替换为 c i c_i ci; 计算矩阵中连通块的数量。
还有一个额外的约束:对于每个 1 ≤ i ≤ q − 1 , 1 ≤ c i ≤ c i + 1 1≤i≤q-1,1≤c_i≤c_ i+1 1≤i≤q−1,1≤ci≤ci+1。
输入格式
第一行有3个整数n,m和,q意义如题。 接下来有q行:第i+1行有三个整数xi,yi和ci。
输出格式
输出一共有q行:第i行有一个整数,表示第i次查询后,矩阵中连通块的数量。
i n p u t input input
3 2 10
2 1 1
1 2 1
2 2 1
1 1 2
3 1 2
1 2 2
2 2 2
2 1 2
3 2 4
2 1 5
o u t p u t output output
2
4
3
3
4
4
4
2
2
4
30分做法:
每次修改后,dfs找图中连通块的个数。时间复杂度 O ( q n m ) O(qnm) O(qnm)。
60分做法:
最多有 100 100 100个 c i c_i ci相等,这意味着图中连通块的大小不超过 100 100 100。
对于每次修改 ( x , y ) (x,y) (x,y),受影响的连通块只是 ( x , y ) , ( x − 1 , y ) , ( x + 1 , y ) , ( x , y − 1 ) , ( x , y + 1 ) (x,y),(x-1,y),(x+1,y),(x,y-1),(x,y+1) (x,y),(x−1,y