W
e
l
c
o
m
e
: )

P6743 [BalticOI 2014 Day2] Senior Postmen 题解

题目描述

P6743 BalticOI 2014 Day2 Senior Postmen

题目解法

看到题目想到直接爆搜。

根据题意,只要找出所有互不相交的简单环即可。题目保证了合法性。

跑 dfs,每次到达一个点 \(u\) 就将其放入栈 \(stk\) 中。如果栈 \(stk\) 中已经有点 \(u\),那么就弹栈。

同时每经过一条边 \(i\),那么就将 \(vis_i\) 设为 \(1\),防止重复计数。

做法和 Tarjan 求联通分量有些相似。

所以:

vector<int> stk;
int ins[maxn], vis[maxn<<1];

void dfs(int u)
{
    for(int i=head[u];i;i=nxt[i])
    {
        if(vis[i]) continue;
        vis[i]=vis[i^1]=1;
        dfs(to[i]);
    }
    if(ins[u])
    {
        while(stk.back()!=u)
        {
            cout<<stk.back()<<' ';
            ins[stk.back()]=0;
            stk.pop_back();
        }
        return cout<<stk.back()<<'\n', void();
    }
    ins[u]=1;
    stk.emplace_back(u);
}

喜提 \(\color{orange} \textsf{55pts}\)TLE on #22 #24


仔细一想,因为每条边只能被使用一次,所以每次可以将 \(head_u\) 更新为 \(nxt_i\)

修改后:(dfs 函数第三行)

    for(int i=head[u];i;i=head[u]=nxt[i])

还是 \(\color{orange} \textsf{55pts}\)。只是变成了 TLE on #22


经过一通乱改,最后采取在 dfs 其余节点之前将 \(head_u\) 更新为 \(nxt_i\),所以循环处将 \(i\) 更新为 \(head_u\)

修改后:(以及写的极丑的栈)

int stk[maxn], *top=stk;
int ins[maxn], vis[maxn<<1];

void dfs(int u)
{
    for(int i=head[u];i;i=head[u])
    {
        head[u]=nxt[i];
        if(vis[i]) continue;
        vis[i]=vis[i^1]=1;
        dfs(to[i]);
    }
    if(ins[u])
    {
        while(*top!=u)
        {
            cout<<*top<<' ';
            ins[*top--]=0;
        }
        return cout<<*top<<'\n', void();
    }
    ins[*++top=u]=1;
}

成功 \(\color{green} \textsf{AC}\)

Code

#include<bits/stdc++.h>
using namespace std;
#define maxn 500005

int head[maxn], to[maxn<<1], nxt[maxn<<1], tot=1;
void link(int u, int v)
{
    to[++tot]=v;
    nxt[tot]=head[u];
    head[u]=tot;
}

int stk[maxn], *top=stk;
int ins[maxn], vis[maxn<<1];

void dfs(int u)
{
    for(int i=head[u];i;i=head[u])
    {
        head[u]=nxt[i];
        if(vis[i]) continue;
        vis[i]=vis[i^1]=1;
        dfs(to[i]);
    }
    if(ins[u])
    {
        while(*top!=u)
        {
            cout<<*top<<' ';
            ins[*top--]=0;
        }
        return cout<<*top<<'\n', void();
    }
    ins[*++top=u]=1;
}

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    int n,m;
    cin>>n>>m;
    for(int i=1, u, v;i<=m;i++)
    {
        cin>>u>>v;
        link(u, v);
        link(v, u);
    }
    dfs(1);
}
posted @ 2024-08-25 20:57  Jimmy-LEEE  阅读(67)  评论(0)    收藏  举报