要让字典序最小,就要让所有字符串按照字典序从小到大排序。
而更新完每个点所有的出边后,由于出边所在的字符串的最后一个字符有可能不是严格从小到大的。
所以不要手贱在将所有串从小到大排序后再将所有点的所有出点从小到大排序。
55pts:
#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define FOR(i,l,r) for(int i=l;i<=r;++i)
#define ROF(i,r,l) for(int i=r;i>=l;--i)
#define mkp make_pair
#define fr first
#define se second
using namespace std;
const int N=1e3+10;
int n,top,tot,len[N],hed[N],cnt[N],in[N],out[N],fa[N];
string s[N],ans[N];
map<pair<char,char>,string>mp;
struct Node {
char fr;
string se;
};
vector<Node>v[N];
int cmp(Node x,Node y) {
if(x.fr!=y.fr) return x.fr<y.fr;
return x.se<y.se;
}
int Get(int x) {
return fa[x]==x?x:fa[x]=Get(fa[x]);
}
void Merge(int x,int y) {
fa[Get(y)]=Get(x);
}
void dfs(int x,string s) {
while(hed[x]<v[x].size()) {
int y=v[x][hed[x]].fr;
string ol=v[x][hed[x]].se;
hed[x]++;
dfs(y,ol);
}
ans[++top]=s;
}
main() {
cin>>n;
FOR(i,1,125) fa[i]=i;
FOR(i,1,n) cin>>s[i];
sort(s+1,s+n+1);
FOR(i,1,n) {
v[s[i][0]].push_back(Node{s[i][s[i].length()-1],s[i]});
Merge(s[i][0],s[i][s[i].length()-1]);
cnt[Get(s[i][0])]=1;
in[s[i][s[i].length()-1]]++,out[s[i][0]]++;
}
int num=0,k=0,st=0,num2=0;
FOR(i,1,125) sort(v[i].begin(),v[i].end(),cmp);
FOR(i,1,125) {
if(in[i]-out[i]==1) num++;
if(out[i]-in[i]==1) num2++,st=st?st:i;
}
FOR(i,1,125) if(Get(i)==i&&(in[i]||out[i])) k++;
if(num+num2!=2&&num+num2||k>1) {
puts("***");
return 0;
}
if(!st) FOR(i,1,125) if(in[i]) st=st?st:i;
dfs(st,"a");
ROF(i,top-1,2) cout<<ans[i]<<".";
cout<<ans[1]<<"\n";
return 0;
}
100pts:
#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define FOR(i,l,r) for(int i=l;i<=r;++i)
#define ROF(i,r,l) for(int i=r;i>=l;--i)
#define mkp make_pair
#define fr first
#define se second
using namespace std;
const int N=1e3+10;
int n,top,tot,len[N],hed[N],cnt[N],in[N],out[N],fa[N];
string s[N],ans[N];
map<pair<char,char>,string>mp;
struct Node {
char fr;
string se;
};
vector<Node>v[N];
int cmp(Node x,Node y) {
if(x.fr!=y.fr) return x.fr<y.fr;
return x.se<y.se;
}
int Get(int x) {
return fa[x]==x?x:fa[x]=Get(fa[x]);
}
void Merge(int x,int y) {
fa[Get(y)]=Get(x);
}
void dfs(int x,string s) {
while(hed[x]<v[x].size()) {
int y=v[x][hed[x]].fr;
string ol=v[x][hed[x]].se;
hed[x]++;
dfs(y,ol);
}
ans[++top]=s;
}
main() {
cin>>n;
FOR(i,1,125) fa[i]=i;
FOR(i,1,n) cin>>s[i];
sort(s+1,s+n+1);
FOR(i,1,n) {
v[s[i][0]].push_back(Node{s[i][s[i].length()-1],s[i]});
Merge(s[i][0],s[i][s[i].length()-1]);
cnt[Get(s[i][0])]=1;
in[s[i][s[i].length()-1]]++,out[s[i][0]]++;
}
int num=0,k=0,st=0,num2=0;
// FOR(i,1,125) sort(v[i].begin(),v[i].end(),cmp);万恶之源!!!
FOR(i,1,125) {
if(in[i]-out[i]==1) num++;
if(out[i]-in[i]==1) num2++,st=st?st:i;
}
FOR(i,1,125) if(Get(i)==i&&(in[i]||out[i])) k++;
if(num+num2!=2&&num+num2||k>1) {
puts("***");
return 0;
}
if(!st) FOR(i,1,125) if(in[i]) st=st?st:i;
dfs(st,"a");
ROF(i,top-1,2) cout<<ans[i]<<".";
cout<<ans[1]<<"\n";
return 0;
}
Hack:
input:
5
aaaaaaabbbbbz
aabbbbbbbbaaa
zaaaaaaaaaaaa
zabbbbbbbbbaa
aaaaaaaaaaazz
output:
aaaaaaaaaaazz.zaaaaaaaaaaaa.aaaaaaabbbbbz.zabbbbbbbbbaa.aabbbbbbbbaaa