问题:路径其实既可以在bfs树的两条不同路径上,也可以在在dfs树的两条不同路径上,但是切记不要广搜一边搜一边查找答案,会导致查找错误的,因为你访问的点还不一定已经构造完成(这么简单的问题都没发现,唉。。。)
题解:
从起点s出发构造一棵树,如果有答案的话,我们会发现除终点外,两条路径一定在两棵不同的子树中,所以只需要枚举除s外的点,看它是否有一条边与其他子树相连。
所以先广搜一遍构造一棵树,然后再广搜一遍靠反边来查找答案。
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<vector> #include<queue> #define maxn 200009 using namespace std; vector<int>v1[maxn],v2[maxn]; bool vis[maxn]; int fa[maxn],num[maxn]; queue<int>q; int st,n,m,cnt,ans[maxn]; void dfs(int x) { ans[++cnt]=x; if (fa[x]!=x) dfs(fa[x]); } void work() { int len=v1[st].size(); for (int i=1;i<=n;i++) vis[i]=false,fa[i]=i,num[i]=i; vis[st]=true; for (int i=0;i<len;i++) { int to=v1[st][i]; q.push(to); fa[to]=st; vis[to]=true; } while (!q.empty()) { int now=q.front(); q.pop(); len=v1[now].size(); for (int i=0;i<len;i++) { int to=v1[now][i]; if (vis[to]) continue; vis[to]=true; num[to]=num[now]; fa[to]=now; q.push(to); } } for (int i=1;i<=n;i++) { if (i==st) continue; int len=v2[i].size(); for (int j=0;j<len;j++) { int to=v2[i][j]; if (fa[i]==to) continue; if ((vis[to])&&(num[to]!=num[i])) { cout<<"Possible"<<endl; cnt=1; ans[1]=i; dfs(to); cout<<cnt<<endl; for (int k=cnt;k>=1;k--) cout<<ans[k]<<" \n"[k==1]; cnt=0; dfs(i); cout<<cnt<<endl; for (int k=cnt;k>=1;k--) cout<<ans[k]<<" \n"[k==1]; return; } } } cout<<"Impossible"<<endl; } int main() { cin>>n>>m>>st; int x,y; for (int i=1;i<=m;i++) { cin>>x>>y; v1[x].push_back(y); v2[y].push_back(x); } work(); return 0; }