uva 1010
【Sol】 DP+最短路
经试验,原先的n个串应该没有相同的
引用《算法艺术与信息学竞赛》P148#include<cstring>
#include<algorithm>
#include<cstdio>
#include<string>
#include<iostream>
#include<queue>
using namespace std;
#define N 22
#define M 500
const int inf=0x3f3f3f3f;
char word[N][N];
bool vis[N][N];
struct node{
int p;
string s;
}d[N][N];
queue<int > Q1,Q2;
int n,len[N];
const char* printans;
//返回 0 无关系
//返回1 S1是S2的前缀 ( L1<L2)
//返回2 S2是S1的前缀 ( L1>L2)
//返回3 相等 ( L1=L2)
//返回>=2 L1>=L2
int isprefix(char *s1, char *s2)
{ int l1=strlen(s1), l2=strlen(s2);
for (int i=0;i<l1&&i<l2;i++)
if (s1[i]!=s2[i])return 0;
if (l1==l2) return 3;
if (l1<l2) return 1;
if (l1>l2) return 2;
}
void Qclear()
{
while (!Q1.empty()) Q1.pop();
while (!Q2.empty()) Q2.pop();
}
bool minize(int a,int b,int p,string s)
{
if (p<d[a][b].p) {d[a][b].p=p; d[a][b].s=s; return 1;}
else if (p==d[a][b].p&&s<d[a][b].s){d[a][b].s=s; return 1;}
return 0;
}
void spfa()
{ Qclear();
memset(vis,0,sizeof(vis));
for (int i=1;i<=n;i++)
for (int j=1;j<=len[i];j++)
if (d[i][j].p!=inf)
{ Q1.push(i); Q2.push(j);
vis[i][j]=1;
}
while (!Q1.empty())
{
int nowa=Q1.front(),nowb=Q2.front();
int p=d[nowa][nowb].p;
string s=d[nowa][nowb].s;
Q1.pop(); Q2.pop();
for (int i=1;i<=n;i++)
{if (isprefix(word[nowa]+nowb,word[i])>=2)
if (minize(nowa,nowb+len[i],p+len[i],s+string(word[i])))
{Q1.push(nowa); Q2.push(nowb+len[i]);}
if (isprefix(word[i],word[nowa]+nowb)>=2)
if (minize(i,len[nowa]-nowb,p+len[nowa]-nowb,s+string(word[nowa]+nowb)))
{Q1.push(i); Q2.push(len[nowa]-nowb);}
}
}
}
void doit()
{
for (int i=1;i<=n;i++)
{scanf("%s",word[i]);
len[i]=strlen(word[i]);
}
for (int i=1;i<=n;i++)
for (int j=1;j<=len[i];j++)
d[i][j].p=inf;
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
if (i!=j)
if (isprefix(word[j],word[i])>=2)
{ d[j][len[i]].p=len[i];
d[j][len[i]].s=string(word[i]);
}
int ans=inf;
string anss="";
spfa();
for (int i=1;i<=n;i++)
if (ans>d[i][len[i]].p)
{ans=d[i][len[i]].p; anss=d[i][len[i]].s;}
else if (ans==d[i][len[i]].p&&anss>d[i][len[i]].s)
anss=d[i][len[i]].s;
printf("%d bits\n%",ans);
const char* printans=anss.c_str();
int hhh=(ans-1)/20;
for (int i=0;i<hhh;i++)
{ for (int j=0;j<20;j++)
printf("%c",*(printans+i*20+j));
printf("\n");
}
for (int j=0;j<ans-hhh*20;j++)
printf("%c",*(printans+j+hhh*20));
printf("\n");
}
int main()
{ int i=0;
while (scanf("%d",&n),n)
{printf("Code %d: ",++i);
doit();
printf("\n");
}
}