Link
首先给出一个有解的必要条件:存在(a
ightarrow c
ightarrow b)的一条点不相交路径。
必要性是显然的。
注意到保证存在(3)条(a
ightarrow b)的点不相交路径,因此这个条件也具有充分性,具体可以通过调整法证明。
那么我们先用最大流找出三条(a
ightarrow b)的路径,然后枚举其中一条作为最后环路中的(a
ightarrow b)的路径,再在残量网络(只考虑这一条(a
ightarrow b)的路径的流量)上跑出(a
ightarrow c
ightarrow b)的路径即可。
#include<queue>
#include<cstdio>
#include<cctype>
#include<vector>
#include<cstring>
#include<algorithm>
const int V=20007,E=220007;
int read(){int x=0,c=getchar();while(isspace(c))c=getchar();while(isdigit(c))(x*=10)+=c&15,c=getchar();return x;}
int n,m,a,b,c,s,t,tot=1,head[V],ver[E],next[E],edge[E],vis[V],pre[V];
std::vector<int>vec[3],pat[3],ans;std::queue<int>q;
void add(int u,int v){ver[++tot]=v,next[tot]=head[u],edge[tot]=1,head[u]=tot,ver[++tot]=u,next[tot]=head[v],head[v]=tot;}
int bfs()
{
while(!q.empty()) q.pop();
memset(vis,0,sizeof vis),q.push(s),vis[s]=1;
for(int i,u,v;!q.empty();) for(i=head[u=q.front()],q.pop();i;i=next[i]) if(edge[i]&&!vis[v=ver[i]]) if(vis[v]=1,pre[v]=i,q.push(v),v==t) return 1;
return 0;
}
int find()
{
if(!bfs())return 0;
for(int p=t;p^s;p=ver[pre[p]^1])--edge[pre[p]],++edge[pre[p]^1];
return 1;
}
int flow()
{
int ans=0;
while(find())++ans;
return ans;
}
void dfs(int u,std::vector<int>&vec)
{
if(u<=n) vec.push_back(u);
if(u==t) return ;
for(int i=head[u];i;i=next[i]) if(edge[i^1]&&~i&1) {dfs(ver[i],vec),++edge[i],--edge[i^1];break;}
}
int check(int id)
{
int f=1;
for(int x:vec[id]) f&=x!=c;
return f;
}
int main()
{
freopen("roundtrip.in","r",stdin),freopen("roundtrip.out","w",stdout);
n=read(),m=read(),a=read(),b=read(),c=read(),s=a+n,t=b;
for(int i=1,u,v;i<=m;++i) u=read(),v=read(),add(u+n,v),add(v+n,u);
for(int i=1;i<=n;++i) add(i,i+n);
for(int i=0;i<3;++i) find();
for(int i=0;i<3;++i) dfs(s,vec[i]);
add(a+n,n+n+1),add(b+n,n+n+1),s=c+n,t=n+n+1;
for(int i=0,f;i<3;++i)
{
if(!check(i)) continue;
for(int j=0;j+1<(int)vec[i].size();++j) for(int k=head[vec[i][j]];k;k=next[k]) if(ver[k]==vec[i][j]+n) edge[k]=0;
f=flow();
for(int j=0;j<f;++j) pat[j].clear(),dfs(s,pat[j]);
if(f==2)
{
if(pat[0].back()==b) std::swap(pat[0],pat[1]);
std::reverse(pat[0].begin(),pat[0].end()),ans=pat[0],ans.push_back(c),ans.insert(ans.end(),pat[1].begin(),pat[1].end()),vec[i].pop_back(),std::reverse(vec[i].begin(),vec[i].end()),ans.insert(ans.end(),vec[i].begin(),vec[i].end()),ans.push_back(a),printf("%d
",(int)ans.size()-1);
for(int x:ans) printf("%d ",x);
return 0;
}
for(int j=0;j+1<(int)vec[i].size();++j) for(int k=head[vec[i][j]];k;k=next[k]) if(ver[k]==vec[i][j]+n) edge[k]=1;
}
puts("-1");
}