zoukankan      html  css  js  c++  java
  • 图论--最小环--Floyd模板

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <vector>
    #include <map>
    #include <stack>
    using namespace std;
    const int INF = 0x3f3f3f3f;
    const int MAXN = 110;
    
    int n, m;               //  n:节点个数, m:边的个数
    int g[MAXN][MAXN];      //  无向图
    int dist[MAXN][MAXN];   //  最短路径
    int r[MAXN][MAXN];      //  r[i][j]: i到j的最短路径的第一步
    int out[MAXN], ct;      //  记录最小环
    
    int solve(int i, int j, int k)
    {   //  记录最小环
        ct = 0;
        while (j != i)
        {
            out[ct++] = j;
            j = r[i][j];
        }
        out[ct++] = i;
        out[ct++] = k;
        return 0;
    }
    
    int main()
    {
        while (scanf("%d%d", &n, &m) != EOF)
        {
            int i, j, k;
            for (i = 0; i < n; i++)
            {
                for (j = 0; j < n; j++)
                {
                    g[i][j] = INF;
                    r[i][j] = i;
                }
            }
            for (i = 0; i < m; i++)
            {
                int x, y, l;
                scanf("%d%d%d", &x, &y, &l);
                --x;
                --y;
                if (l < g[x][y])
                {
                    g[x][y] = g[y][x] = l;
                }
            }
            memmove(dist, g, sizeof(dist));
            int Min = INF;              //  最小环
            for (k = 0; k < n; k++)
            {                           //  Floyd
                for (i = 0; i < k; i++) //  一个环中的最大结点为k(编号最大)
                {
                    if (g[k][i] < INF)
                    {
                        for (j = i + 1; j < k; j++)
                        {
                            if (dist[i][j] < INF && g[k][j] < INF && Min > dist[i][j] + g[k][i] + g[k][j])
                            {
                                Min = dist[i][j] + g[k][i] + g[k][j];
                                solve(i, j, k);     //  记录最小环
                            }
                        }
                    }
                }
                for (i = 0; i < n; i++)
                {
                    if (dist[i][k] < INF)
                    {
                        for (j = 0; j < n; j++)
                        {
                            if (dist[k][j] < INF && dist[i][j] > dist[i][k]+dist[k][j])
                            {
                                dist[i][j] = dist[i][k] + dist[k][j];
                                r[i][j] = r[k][j];
                            }
                        }
                    }
                }
            }
            if (Min < INF)
            {
                for (ct--; ct >= 0; ct--)
                {
                    printf("%d", out[ct] + 1);
                    if (ct)
                    {
                        printf(" ");
                    }
                }
            }
            else
            {
                printf("No solution.");
            }
            printf("
    ");
        }
    
        return 0;
    }
  • 相关阅读:
    算法
    算法
    算法
    算法
    算法
    【PAT】B1064 朋友数(20 分)
    【PAT】B1065 单身狗(25 分)
    【PAT】B1066 图像过滤(15 分)
    【PAT】B1067 试密码(20 分)
    【PAT】B1068 万绿丛中一点红(20 分)
  • 原文地址:https://www.cnblogs.com/lunatic-talent/p/12798668.html
Copyright © 2011-2022 走看看