2017-2018 ACM-ICPC, NEERC, Northern Subregional Contest G.Grand Test (Gym 101612G) 题解

2017-2018 ACM-ICPC, NEERC, Northern Subregional Contest G.Grand Test 题解

  • 题目链接
  • 题意
  • 题解
  • 代码

题目链接

Gym 101612G

题意

在一个图中找两个点,使这两个点之间有三条不相交路径,并输出这三条路径。

题解

使用tarjan算法的思想,设dfn[x]为点x的访问时间顺序,low1[x]为x能到达的最小时序,end1[x]为x到达最小时序的路径的末端节点,low2[x]为x能到达的次小时序,end2[x]为x能到达次小时序的路径的末端节点,如果点x有两条路径能到达时序比它小的节点,即low2[x]

代码

#include 
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 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 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]

你可能感兴趣的:(tarjan)