洛谷 P1127 词链——题解

洛谷P1127题解


传送锚点


摸鱼环节

词链

题目描述

如果单词 \(X\) 的末字母与单词 \(Y\) 的首字母相同,则 \(X\)\(Y\) 可以相连成 \(X.Y\)。(注意:\(X\)\(Y\) 之间是英文的句号 .)。例如,单词 dog 与单词 gopher,则 doggopher 可以相连成 dog.gopher

另外还有一些例子:

  • dog.gopher
  • gopher.rat
  • rat.tiger
  • aloha.aloha
  • arachnid.dog

连接成的词可以与其他单词相连,组成更长的词链,例如:

aloha.arachnid.dog.gopher.rat.tiger

注意到,. 两边的字母一定是相同的。

现在给你一些单词,请你找到字典序最小的词链,使得每个单词在词链中出现且仅出现一次。注意,相同的单词若出现了 \(k\) 次就需要输出 \(k\) 次。

输入格式

第一行是一个正整数 \(n\)\(1 \le n \le 1000\)),代表单词数量。

接下来共有 \(n\) 行,每行是一个由 \(1\)\(20\) 个小写字母组成的单词。

输出格式

只有一行,表示组成字典序最小的词链,若不存在则只输出三个星号 ***

样例 #1

样例输入 #1

6
aloha
arachnid
dog
gopher
rat
tiger

样例输出 #1

aloha.arachnid.dog.gopher.rat.tiger

提示

  • 对于 \(40\%\) 的数据,有 \(n \leq 10\)
  • 对于 \(100\%\) 的数据,有 \(n \leq 1000\)

最爱水题解的我又来蟹题解了,这道词链题生动形象的为我们展现了蓝水题的强度,于是这道图论题就被我们干掉了。


正片开始

观察到数据范围很小,说明能给暴力的空间比较充裕,但纯暴力肯定会挂。


1.考虑暴力

暴力的话,直接建立邻接表,将字符串\(a[i]\)数组进行排序后枚举每个点暴搜一下,这里展示搜索代码。

code:

void dfs(int u,string s,int cnt)//u当前遍历点的标号,s为答案,cnt为加入字符串的数量
{
    if(cnt==n)//递归出口
    {
        s[s.length()-1]=' ';
        cout<<s;
        exit(0);
    }
    for(auto v:g[u])//遍历邻接表
    {
        if(vis[v]==0)
        {
            vis[v]=1;
            dfs(v,s+a[v]+'.',cnt+1);
            vis[v]=0;
        }
    }
}

2.优化部分

我们从样例中可以发现,对于一条合法的答案,其一定为欧拉通路或欧拉回路。

一个点如果能作为起点,那其在字符串首出现次数一定比在字符串尾出现的次数多一,这样就可以对枚举起点处进行优化。

同时需特判回路的特殊情况。

code:

for(int i=1;i<=n;i++)
{
    in[a[i][0]]++;
    out[a[i][a[i].length()-1]]++;
}//统计每个字母作为首或尾出现的次数
for(int i=1;i<=n;i++)
{
    if(in[a[i][0]]==out[a[i][0]]+1)//满足条件才进入答案处理
    {
        vis[i]=1;
        dfs(i,a[i]+'.',1);
        vis[i]=0;
    }
}
vis[1]=1;
dfs(1,a[1]+'.',1);//特判欧拉回路
vis[1]=0;
cout<<"***"<<endl;//无解

完整代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e4+10;
int n,vis[N],in[N],out[N];
string a[N];
vector<int>g[N];
void dfs(int u,string s,int cnt)
{
    if(cnt==n)
    {
        s[s.length()-1]=' ';
        cout<<s;
        exit(0);
    }
    for(auto v:g[u])
    {
        if(vis[v]==0)
        {
            vis[v]=1;
            dfs(v,s+a[v]+'.',cnt+1);
            vis[v]=0;
        }
    }
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i];
    sort(a+1,a+n+1);
    for(int i=1;i<=n;i++)
    {
        in[a[i][0]]++;
        out[a[i][a[i].length()-1]]++;
    }
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            if(i!=j&&a[i][a[i].length()-1]==a[j][0]) g[i].push_back(j);
    for(int i=1;i<=n;i++)
    {
        if(in[a[i][0]]==out[a[i][0]]+1)
        {
            vis[i]=1;
            dfs(i,a[i]+'.',1);
            vis[i]=0;
        }
    }
    vis[1]=1;
    dfs(1,a[1]+'.',1);
    vis[1]=0;
    cout<<"***"<<endl;
    return 0;
}

完结收工!!!!!

个人主页

看完点赞,养成习惯

\(\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\)

posted @ 2024-08-10 10:45  Nightmares_oi  阅读(5)  评论(0编辑  收藏  举报