求有向图的最长路径

题目:有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编辑  收藏  举报

导航