题目:
分析:这个题放这里我当然会做了。直接进行状态转化,单词转化为点,构造一个有向的图。
单词要先排序。
然后问题转化为在图中寻找能走完全部的最小路径了。
具体怎么找呢?应该首先从0开始,能遍历的都标记,然后从没标记的中找最小的,遍历看看没标记的是否可以全部标记了,以此类推,???半个月后看到自己瞎写真无语。
代码:
只优化了:排序后从最小的开始。
#include<bits/stdc++.h>
using namespace std;
int m;
vector<string> vs;
vector<vector<int> > vvb;
vector<vector<int> > vve;
int done[1050];
bool dfs(int x,int num,vector<string> &v)
{
if(num==vs.size())
{
return 1;
}
char ee=vs[x][vs[x].size()-1];
for(int i=0;i<vvb[ee-'a'].size();i++)
{
if(done[vvb[ee-'a'][i]]==1) continue;
vector<string> vv=v;
v.push_back(vs[vvb[ee-'a'][i]]);
done[vvb[ee-'a'][i]]=1;
if(dfs(vvb[ee-'a'][i],num+1,v)) return 1;
v=vv;
done[vvb[ee-'a'][i]]=0;
}
return 0;
}
int main()
{
cin>>m;
vector<int> v;
for(int i=0;i<26;i++)
{
vvb.push_back(v);
}
for(int i=0;i<m;i++)
{
string ss;
cin>>ss;
vs.push_back(ss);
}
sort(vs.begin(),vs.end());
for(int i=0;i<m;i++)
{
char bb=vs[i][0];
vvb[bb-'a'].push_back(i);
}
memset(done,0,sizeof(done));
int begin=-1;
vector<string> vs22;
for(int i=0;i<m;i++)
{
done[i]=1;
if(dfs(i,1,vs22)) {
begin=i; break;
};
done[i]=0;
}
if(begin==-1) {
cout<<"***";
return 0;
}
cout<<vs[begin];
done[begin]=1;
for(int i=0;i<vs22.size();i++) cout<<'.'<<vs22[i];
}
优化,入度为0的点,最多有两个。
没有的话,再用上面的方法。
挺简单的代码写了好长时间了,懒得搞了。