已AC,但有一点疑惑

P4683 [IOI2008] Type Printer

Kevin911 @ 2023-12-01 21:22:14

我的第一种想法是建好trie树后,在遍历一遍求出每个节点距离最远叶结点最远的一个,然后计算答案是最后一个遍历,但是为什么这样子不行。

//错误
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e6+10;
int trie[maxn][27],endds[maxn],dis[maxn],mx[maxn],cnt,len;
char ans[maxn];
void insert(string s)
{
    int d=0;
    for(int i=0;i<s.size();i++)
    {
        int k=s[i]-'a';
        if(!trie[d][k]) trie[d][k]=++cnt;
        d=trie[d][k];
    }
    endds[d]=1;
}
void dfs1(int u)
{
    for(int i=0;i<26;i++)
        if(trie[u][i])
        {
            dfs1(trie[u][i]);
            if(dis[u]<dis[trie[u][i]]+1)
            {
                mx[u]=i;
                dis[u]=max(dis[u],dis[trie[u][i]]+1);
            }
        }
}
void dfs2(int u)
{
    if(endds[u]) ans[++len]='P';
    for(int i=0;i<26;i++)
        if(trie[u][i]&&mx[u]!=i)
        {
            ans[++len]=i+'a';
            dfs2(trie[u][i]);
        }
    if(mx[u])
    {
        ans[++len]=mx[u]+'a';
        dfs2(trie[u][mx[u]]);       
    }
    ans[++len]='-';
}
signed main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        string s;
        cin>>s;
        insert(s);
    }
    dfs1(0);
    dfs2(0);
    while(ans[len]=='-') len--;
    cout<<len<<endl;
    for(int i=1;i<=len;i++) cout<<ans[i]<<endl;
}

感觉跟正确做法差异不大(把最长序列给标记了统计答案时最后遍历),所以是什么原因呢

//正确
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e6+10;
int trie[maxn][27],endds[maxn],dis[maxn],mx[maxn],cnt;
string ans,t;
bool vis[maxn][27];
void insert(string s)
{
    int d=0;
    for(int i=0;i<s.size();i++)
    {
        int k=s[i]-'a';
        if(!trie[d][k]) trie[d][k]=++cnt;
        d=trie[d][k];
    }
    endds[d]=1;
}
void dfs1(int u)
{
    for(int i=0;i<26;i++)
        if(trie[u][i])
        {
            dfs1(trie[u][i]);
            if(dis[u]<dis[trie[u][i]]+1)
            {
                mx[u]=i;
                dis[u]=max(dis[u],dis[trie[u][i]]+1);
            }
        }
}
void update()
{
    int d=0;
    for(int i=0;i<t.size();i++)
    {
        int k=t[i]-'a';
        vis[d][k]=1;
        d=trie[d][k];
    }
}
void dfs2(int u)
{
    if(endds[u]) ans+='P';
    for(int i=0;i<26;i++)
        if(trie[u][i]&&!vis[u][i])
        {
            ans+=(i+'a');
            dfs2(trie[u][i]);
            ans+='-';
        }
    for(int i=0;i<26;i++)
        if(trie[u][i]&&vis[u][i])
        {
            ans+=(i+'a');
            dfs2(trie[u][i]);
            ans+='-';
        }
}
signed main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        string s;
        cin>>s;
        insert(s);
        if(s.size()>t.size()) t=s;
    }
    update();
    dfs2(0);
    int len=ans.size()-1;
    while(ans[len]=='-') len--;
    cout<<len+1<<endl;
    for(int i=0;i<=len;i++) cout<<ans[i]<<endl;
}

|