timus_1003_floyd_warshall

题目的意思:

  一条路径的起点和终点相同,就是一只「环」。

timus_1003_floyd_warshall

有向图的环,可以特地称作​​「有向环」;无向图的环,可以特地称作​​「无向环」。环上每个点都恰好连着两条边。

无向环以另一种角度来看,就是两条路径,两条路径的起点相同、终点也相同。

习惯规定一个环至少三个点。

  藉由Floyd-Warshall Algorithm 的过程,顺手穷举所有可能的最小环。代码如下:

#include <stdio.h>

#include <string.h>



int n;//交叉点的数量

int m;//路径的跳数

int edge[101][101];//记录每条边的情况,以及使用情况

int d[101][101];//记录顶点间距离

int path[101][101];//记录路径

int ans_path[101];//答案路径

int ans_len;//记录路径的长度

#define INFINITE 10000000

int min = INFINITE;//源到源的最小路径长度

//获得路径

void get_path(int i, int j)

{

    ans_path[ans_len ++] = j;

    if (i == j)    

        return;

    get_path(i, path[i][j]);

}



int main(void)

{

    int i, j, k, source, destination, distance, flag1;



    //输入数据

    while (1)    

    {

        scanf("%d", &n);    

        if (n == -1)

            break;

        scanf("%d", &m);

        //初始化edge

        for (i = 1; i <= n; i ++)

        {

            edge[i][i] = INFINITE;

            path[i][i] = INFINITE;

            for (j = i; j <= n; j ++)

                edge[i][j] = edge[j][i] = INFINITE;

        }

        for (i = 0; i < m; i ++)

        {

            scanf("%d%d%d", &source, &destination, &distance);    

            if (edge[source][destination] > distance)

            {

                edge[source][destination] = edge[destination][source] = distance;

                path[source][destination] = source;

                path[destination][source] = destination;

            }

        }

        min = INFINITE;

        memcpy(d, edge, sizeof(edge));

        for (k = 1; k <= n; k ++)

        {

            for (i =1; i < k; i ++)

                for (j = 1; j < k; j ++)

                    if (i != j)

                    {

                        if ( edge[k][i] + d[i][j] + edge[j][k] < min)        

                        {

                            min = edge[k][i] + d[i][j] + edge[j][k];    

                            ans_len = 0;

                            ans_path[ans_len ++] = k;

                            get_path(i, j);

                        }

                    }

            for (i = 1; i <= n; i ++)    

            {

                for (j = 1; j <=n; j ++)

                {

                    if (d[i][j] > d[i][k] + d[k][j])

                    {

                        d[i][j] = d[i][k] + d[k][j];

                        path[i][j] = path[k][j];

                    }

                    //printf("%d:%d ", d[i][j], path[i][j]);

                }

            //    printf("\n");

            }

        //    printf("\n\n");

        }

        if (min == INFINITE)

            printf("No solution.\n");

        else

        {

            while (ans_len)    

                printf("%d ", ans_path[-- ans_len]);

            printf("\n");

        }

    }

    return 0;

}

 

你可能感兴趣的:(floyd)