URAL 1004 Sightseeing Trip 无向图最小环

来源:互联网 发布:网络小鲜肉图片大全 编辑:程序博客网 时间:2024/06/05 15:02

题目:

https://vjudge.net/problem/14074

题意:

给定一个有n个点的无向图,有m条无向边,求图中一个至少包含三个点的环,并输出环上的点,有多解任意输出一个即可,没有这样的环则输出No solution.

思路:

可以用floyd算法求解最小环,然后记录路径输出即可。
关于记录路径:定义pro[i][j]为点i到点j路径上的倒数第二个点,倒数第一个自然是j,初始化pro[i][j]为i。当dis[i][j] > dis[i][k] + dis[k][j]成立时,意味着点i到点j的路径要改成点i到点k再到点j,而dis[k][j]已知,意味着pro[k][j]已知,即点k到点j的路径已知,所以此时应该把pro[k][j]存到pro[i][j]中,即pro[i][j] = pro[k][j]

#include <bits/stdc++.h>using namespace std;const int N = 110, INF = 1<<28;int n, m, tot;int g[N][N], dis[N][N], pro[N][N], path[N];int floyd(){    int res = INF;    for(int k = 1; k <= n; k++)    {        for(int i = 1; i < k; i++)            for(int j = i+1; j < k; j++)            {                int tmp = dis[i][j] + g[i][k] + g[k][j];                if(res > tmp)                {                    res = tmp;                    tot = 0;                    int p = j;                    while(p != i)                    {                        path[tot++] = p;                        p = pro[i][p];                    }                    path[tot++] = i, path[tot++] = k;                }            }        for(int i = 1; i <= n; i++)            for(int j = 1; j <= n; j++)                if(dis[i][j] > dis[i][k] + dis[k][j])                {                    dis[i][j] = dis[i][k] + dis[k][j];                    pro[i][j] = pro[k][j];                }    }    return res;}int main(){    while(scanf("%d", &n), n != -1)    {        scanf("%d", &m);        for(int i = 1; i <= n; i++)            for(int j = 1; j <= n; j++)            {                if(i == j) g[i][j] = dis[i][j] = 0;                else g[i][j] = dis[i][j] = INF;                pro[i][j] = i;            }        for(int i = 1; i <= m; i++)        {            int v, u, c;            scanf("%d%d%d", &v, &u, &c);            g[v][u] = g[u][v] = dis[v][u] = dis[u][v] = min(g[v][u], c);        }        int res = floyd();        if(res == INF) printf("No solution.\n");        else        {            for(int i = tot-1; i >= 0; i--) printf("%d%c", path[i], i == 0 ? '\n' : ' ');        }    }    return 0;}
0 0
原创粉丝点击