CF925D 题解
思路
把初始开启的走廊放到一张图上,发现这张图上的简单路径一定能走,所以这张图上
考虑通过别的方法走到
由于这已经是最短的初始不完整的路径,所以若最短路长度
分析这种路径什么时候存在,发现只要有点
如果没有这种路径,那么初始与
考虑这种路径什么时候存在,发现同上只要有点
由于在完全图上每次走边都会使出发点被完全孤立开来,只会让完全图连通块越来越小,所以这种路径也不存在时就可以确定无解了。
具体寻找路径时直接遍历所有的出边即可,时间复杂度的话第一种路径时每条边只会作为
代码
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
const int N=3e5+10;
int n,m,fa[N],dis[N],te[N];
vector <int> edge[N];
queue <int> q;
signed main()
{
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
cin>>n>>m;
for(int i=1;i<=m;i++)
{
int u,v; cin>>u>>v;
edge[u].push_back(v),edge[v].push_back(u);
}
q.push(n),dis[n]=1;
while(q.size())
{
int u=q.front(); q.pop();
for(int v:edge[u]) if(!dis[v]) dis[v]=dis[u]+1,fa[v]=u,q.push(v);
}
if(dis[1]&&dis[1]<=5)
{
cout<<dis[1]-1<<'\n'; int p=1;
while(p!=n) cout<<p<<' ',p=fa[p];
cout<<n; return 0;
} //原图最短路
for(int x:edge[1]) te[x]=1;
for(int x:edge[1]) for(int y:edge[x]) if(y!=1&&te[y]!=1)
{
cout<<4<<'\n'<<1<<' '<<x<<' '<<y<<' '<<1<<' '<<n;
return 0;
} //第一种
for(int x:edge[1])
{
for(int y:edge[x]) te[y]=x;
for(int y:edge[x]) if(y!=1) for(int z:edge[y]) if(z!=x&&te[z]!=x)
{
cout<<5<<'\n'<<1<<' '<<x<<' '<<y<<' '<<z<<' '<<x<<' '<<n;
return 0;
}
} //第二种
cout<<-1;
return 0;
}