求有向图的最长路径
题目:有n 个长为m+1 的字符串,如果某个字符串的最后m 个字符与某个字符串的前m 个字符匹配,则两个字符串可以联接,
问这n 个字符串最多可以连成一个多长的字符串,如果出现循环,则返回错误。
这个题目转化为图来做,设每个字符串看做一个顶点,如果(u,v)满足u的后m个字符和v的前m个字符匹配,则连边,权值设置为1即可。
然后针对建好的图,进行拓扑排序,并检查是否有环,如果有环,直接返回false,如果互换,则进行求最长路径。
求最长路径,我们可以根据floy来求,算法中直接将最短改为最长即可。下面是一种新的方法求最长路径,用到拓扑排序的结果。
该思路的本质是利用动态规划,假设dist[v]表示以v结尾的最长路径,那么dist[v]=max{dist[u]+edge[u][v], dist[v]}.其中u是
v的前驱,正好对应了拓扑排序的顺序,我们按照拓扑顺序依次就即可,由于每个入度为0的顶点都有可能产生最长的那条路径,所以依次
求出来每个入度0顶点所产生的所有路径。代码入下:
//topret存放拓扑排序结果
int getMaxPath(int n)
{
memset(dist, 0, sizeof(dist));
int i = 0, j = 0, k = 0;
int maxd = 0;
for(i = 0; i < n; i++)
{
if(indegree[i] != 0)
continue;
//i为入度为0的顶点,作为本次的原点,计算到每个点的最长路径
memset(dist, 0, sizeof(dist));
for(j = 0; j < n; j++)
{
//本次循环计算以j结尾的最长路径
if( j == i)
continue;
for(k = 0; k < j; k++)
{
if(graph[topret[k]][topret[j]] == 1) //有路
{
if(dist[topret[k]] + 1 > dist[topret[j]])
dist[topret[j]] = dist[topret[k]] + 1;
}
}
if(dist[topret[j]] > maxd)
maxd = dist[topret[j]];
}
}
return maxd;
}
posted on 2012-10-06 12:26 buptLizer 阅读(12277) 评论(0) 编辑 收藏 举报