有n 个长为m+1 的字符串, 如果某个字符串的最后m 个字符与某个字符串的前m 个字符匹配,则两个字符串可以联接, 问这n 个
字符串最多可以连成一个多长的字符串,如果出现循环,则返回错误。
思路:利用弗洛伊德算法可求最长路径。
#include <iostream>
#include <string>
using namespace std;
#define INFINITY -100000 //求最长路径时,邻接矩阵初始化时应该设置成最小值
typedef struct graph
{
string vertex[10];
int arc[10][10];
int num_vertex;
int num_edge;
}graph;
int max=INFINITY,posi,posj;
bool largestpath(graph &g, int d[10][10], int p[10][10])
{
int i,j,k,m;
cout<<"请输入字符串个数:";
cin>>g.num_vertex;
cout<<"请输入字符串:";
for(i=0;i<g.num_vertex;i++)
cin>>g.vertex[i];
cout<<"请输入m的值:";
cin>>m;
for(i=0;i<g.num_vertex;i++) //邻接矩阵初始化
for(j=0;j<g.num_vertex;j++)
g.arc[i][j] = INFINITY;
for(i=0;i<g.num_vertex;i++)
for(j=0;j<g.num_vertex;j++)
{
if(g.vertex[i].substr(g.vertex[i].size()-m,m) == g.vertex[j].substr(0,m))//首尾匹配,则成为一条边,权值为1
g.arc[i][j] = 1;
else
g.arc[i][j] = INFINITY;
}
for(i=0;i<g.num_vertex;i++)
for(j=0;j<g.num_vertex;j++)
{
d[i][j] = g.arc[i][j];
p[i][j] = j;
}
for(k=0;k<g.num_vertex;k++)
for(i=0;i<g.num_vertex;i++)
for(j=0;j<g.num_vertex;j++)
{
if(d[i][j] < d[i][k]+d[k][j])//最长路径需要取最大值,这和求最短路径正好相反
{
d[i][j] = d[i][k]+d[k][j];
p[i][j] = p[i][k];
}
if(d[i][j] > max) //记录当前最长路径
{
max = d[i][j];
posi = i;
posj = j;
}
}
for(i=0;i<g.num_vertex;i++)//判断是否出现循环
if(g.arc[i][i] != INFINITY)
return false;
return true;
}
int main()
{
graph g;
int d[10][10];
int p[10][10];
bool flag = largestpath(g,d,p);
if(flag==false)
cout<<"存在循环!"<<endl;
else
{
cout<<"最长字符串链为:"<<endl;
int num=0;
int i = posi,j=posj;
cout<<g.vertex[i];
num++;
int k = p[i][j];
while(k!=j)
{
cout<<"->"<<g.vertex[k];
k = p[k][j];
num++;
}
cout<<"->"<<g.vertex[j]<<endl;
num++;
cout<<"最长字符串链长度为"<<num<<endl;
}
return 0;
}
参考:http://blog.csdn.net/cxllyg/article/details/7606599