2017-2018 ACM-ICPC, NEERC, Northern Subregional Contest G.Grand Test (Gym 101612G) 題解
阿新 • • 發佈:2018-12-15
2017-2018 ACM-ICPC, NEERC, Northern Subregional Contest G.Grand Test 題解
題目連結
題意
在一個圖中找兩個點,使這兩個點之間有三條不相交路徑,並輸出這三條路徑。
題解
使用tarjan演算法的思想,設dfn[x]為點x的訪問時間順序,low1[x]為x能到達的最小時序,end1[x]為x到達最小時序的路徑的末端節點,low2[x]為x能到達的次小時序,end2[x]為x能到達次小時序的路徑的末端節點,如果點x有兩條路徑能到達時序比它小的節點,即low2[x]<dfn[x],則x到low2[x]這個點之間存在三條不相交路徑。
程式碼
#include <bits/stdc++.h> using namespace std; #define N 100010 int head[N],to[N*2],pre[N*2],fa[N],dfn[N],low1[N],low2[N],end1[N],end2[N],node[N]; int n,m,e,cnt; bool flag; vector<int> path; void addedge(int x,int y) { to[e]=y;pre[e]=head[x];head[x]=e++; } void init() { for(int i=1;i<=n;++i) { head[i]=-1;dfn[i]=0; } e=cnt=0; } void update(int x,int d,int y) { if(d<low1[x]) { low2[x]=low1[x];end2[x]=end1[x]; low1[x]=d;end1[x]=y; } else if(d<low2[x]) { low2[x]=d;end2[x]=y; } } void get_path(int s,int t,bool rev) { vector<int> vec; for(int i=s;i!=t;i=fa[i]) vec.push_back(i); vec.push_back(t); if(rev) reverse(vec.begin(),vec.end()); for(int x:vec) path.push_back(x); } void print_path() { printf("%d ",path.size()); for(int x:path) printf("%d ",x); printf("\n"); } void tarjan(int x,int p) { dfn[x]=low1[x]=low2[x]=++cnt; node[cnt]=x;end1[x]=end2[x]=x; for(int i=head[x];i!=-1;i=pre[i]) { int y=to[i]; if(y==p) continue; if(!dfn[y]) { fa[y]=x; tarjan(y,x); update(x,low1[y],end1[y]); } else if(dfn[y]<dfn[x]) update(x,dfn[y],x); } if(!flag&&low2[x]<dfn[x]) { int s=x,t=node[low2[x]]; printf("%d %d\n",s,t); path.clear(); get_path(s,t,false); print_path(); path.clear(); get_path(end2[x],s,true); path.push_back(t); print_path(); path.clear(); get_path(end1[x],s,true); get_path(t,node[low1[x]],true); print_path(); flag=true; } } int main() { freopen("grand.in","r",stdin); freopen("grand.out","w",stdout); int ca,x,y; scanf("%d",&ca); while(ca--) { scanf("%d%d",&n,&m); init(); for(int i=1;i<=m;++i) { scanf("%d%d",&x,&y); addedge(x,y);addedge(y,x); } flag=false; for(int i=1;i<=n;++i) if(!dfn[i]) tarjan(i,-1); if(!flag) puts("-1"); } return 0; }