这道题用深搜可以,广搜也行
先找到所以可达的点,反向建图即可
然后从起点扩展,注意是字典序最短,而不是路径最短
在扩展的过程中,如果点没走过并且可达则加入队列,这个时候就可以直接break掉了
因为对于当前可达的点来说一定可达
是按照字典序走的
如果发现某个点的扩展点是遍历过的并且是可达的,那么存在一个循环
否则一定可以得到答案
这里要求记录答案,直接用前项链表即可
#include<bits/stdc++.h>
using namespace std;
#define maxm 100010
int vis[maxm],st[maxm];
vector<int>G[maxm];
vector<int>T[maxm];
pair<int,int> pre[maxm];
int n;
char oper[]={'a','b'};
vector<int>inx[maxm];
int bfs(int type){
if(type==0){
queue<int>q;
q.push(n-1);
st[n-1]=1;
while(q.empty()==false){
int u=q.front();q.pop();
for(int i=0;i<(int)T[u].size();i++){
int v=T[u][i];
if(st[v]) continue;
st[v]=1;
q.push(v);
}
}
if(st[0]) return 1;
return 0;
}
memset(pre, -1, sizeof pre);
queue<int>q;
q.push(0);
vis[0]=1;
while(q.empty()==false){
int u=q.front();q.pop();
if(u==n-1) {
return 1;
}
for(int i=0;i<(int)G[u].size();i++){
int v=G[u][i];
if(vis[v]){
if(st[v]) return 0;
continue;
}
if(st[v]==0) continue;
vis[v]=1;
q.push(v);
pre[v]={u,inx[u][i]};
break;
}
}
return 0;
}
int main(){
cin>>n;
for(int i=0;i<n;i++){
int x;
cin>>x;
if(x+i>=0&&x+i<n) {
G[i].push_back(x+i);
T[x+i].push_back(i);
inx[i].push_back(0);
}
}
for(int i=0;i<n;i++) {
int x;
cin>>x;
if(x+i>=0&&x+i<n){
G[i].push_back(x+i);
T[x+i].push_back(i);
inx[i].push_back(1);
}
}
if(bfs(0)==0) cout<<"No solution!\n";
else {
if(bfs(1)==0) cout<<"Infinity!\n";
else {
string str;
// cout<<pre[n-1].first;
for(int i=n-1;i!=0;i=pre[i].first){
str+=oper[pre[i].second];
}
// cout<<str.size()<<str;
for(int i=str.size()-1;i>=0;i--) cout<<str[i];
}
}
return 0;
}