最小环

[poj 1734] (http://poj.org/problem?id=1734)

题目描述:
Sightseeing trip
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 5500 Accepted: 2112 Special Judge
Description

There is a travel agency(中介) in Adelton town on Zanzibar island. It has decided to offer its clients(顾客), besides many other attractions, sightseeing the town. To earn as much as possible from this attraction, the agency has accepted a shrewd(精明的,狡猾的) decision: it is necessary to find the shortest route which begins and ends at the same place. Your task is to write a program which finds such a route.

In the town there are N crossing points numbered from 1 to N and M two-way roads(双向公路) numbered from 1 to M. Two crossing points(交点) can be connected by multiple roads, but no road connects a crossing point with itself. Each sightseeing route is a sequence of road numbers y_1, …, y_k, k>2. The road y_i (1<=i<=k-1) connects crossing points x_i and x_{i+1}, the road y_k connects crossing points x_k and x_1. All the numbers x_1,…,x_k should be different.The length of the sightseeing route is the sum of the lengths of all roads on the sightseeing route, i.e. L(y_1)+L(y_2)+…+L(y_k) where L(y_i) is the length of the road y_i (1<=i<=k). Your program has to find such a sightseeing route, the length of which is minimal, or to specify(指定) that it is not possible,because there is no sightseeing route in the town.
Input

The first line of input contains two positive integers: the number of crossing points N<=100 and the number of roads M<=10000. Each of the next M lines describes one road. It contains 3 positive integers: the number of its first crossing point, the number of the second one, and the length of the road (a positive integer less than 500).
Output

There is only one line in output. It contains either a string ‘No solution.’ in case there isn’t any sightseeing route, or it contains the numbers of all crossing points on the shortest sightseeing route in the order how to pass them (i.e. the numbers x_1 to x_k from our definition of a sightseeing route), separated by single spaces. If there are multiple sightseeing routes of the minimal length, you can output any one of them.
Sample Input

5 7
1 4 1
1 3 300
3 1 10
1 2 16
2 3 100
2 5 15
5 3 20
Sample Output

1 3 5 2
Source

CEOI 1999

题目分析:
由于是双向公路,即可以将其看成无向图,即本题要解决的问题就是找到所有路径中存在的路径最短的最小环,并把环上的每个节点都输出即可。
算法:Floyd算法拓展找最小环+回溯记录路径

代码实现:

#include <iostream>
#include <stdio.h>
using namespace std;

const int MAX=0x7fffffff;
int n,m;
int map[110][110];//记录i和j之间的距离长度
int dist[110][110];//记录i和j之间的最短路径长度
int pre[110][110];//记录他的上个节点
int path[110];//记录经过的点

int min(int x,int y)
{
    return x<=y? x:y;
}

int main()
{
    int a,b,c;
    int M;
    int num;
    M=MAX/10;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=n; j++)
            {
                map[i][j]=dist[i][j]=M;
                pre[i][j]=i;
            }
        }
        while(m--)
        {
            scanf("%d%d%d",&a,&b,&c);
            if(c<map[a][b])
            {
                map[a][b]=map[b][a]=c;
                dist[a][b]=dist[b][a]=c;
            }
        }
        int ans=M;
        for(int k=1; k<=n; k++)
        {
            for(int i=1; i<k; i++)
            {
                for(int j=i+1; j<k; j++)
                {
                    int pp=dist[i][j]+map[k][i]+map[k][j];
                    if(pp<ans)
                    {
                        ans=pp;
                        num=0;
                        int p=j;
                        while(p!=i)//更新他的上个节点
                        {
                            path[num++]=p;
                            p=pre[i][p];
                        }
                        path[num++]=i;
                        path[num++]=k;
                    }
                }
            }
            for(int i=1; i<=n; i++)
            {
                for(int j=1; j<=n; j++)
                {
                    if(dist[i][j]>dist[k][j]+dist[i][k])//更新最短路径和当前节点的上一个节点
                    {
                        dist[i][j]=dist[i][k]+dist[k][j];
                        pre[i][j]=pre[k][j];
                    }
                }
            }
        }
        if(ans==M) printf("No solution.\n");
        else
        {
            for(int i=0; i<num; i++)
            {
                printf(i==num-1?"%d\n":"%d ",path[i]);
            }
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
最小搜索算法可以通过深度优先搜索(DFS)来实现。以下是使用 Python 实现最小搜索的示例代码: ```python def find_minimum_cycle(edges): min_cycle = float('inf') for i in range(len(edges)): visited = [False] * len(edges) stack = [(i, 0)] while stack: node, dist = stack.pop() if visited[node]: min_cycle = min(min_cycle, dist) break visited[node] = True for next_node in edges[node]: stack.append((next_node, dist + 1)) return min_cycle ``` 在以上代码中,`edges` 是一个邻接表,表示图中每个节点所连接的节点。函数首先遍历图中的每个节点,然后对于每个节点,使用 DFS 找出从该节点出发的最小。为了实现这一点,我们使用 `visited` 来跟踪访问过的节点,并使用 `stack` 来存储待访问的节点。在 DFS 的过程中,我们使用 `dist` 来记录当前节点与起始节点的距离。如果在 DFS 过程中访问到了一个已经被访问过的节点,那么我们就找到了一个,并且可以计算出该的长度。最后,我们返回最小的长度。 需要注意的是,以上实现中使用了一个 `min_cycle` 变量来维护最小的长度。如果找到了比当前最小更小的,那么我们就更新 `min_cycle` 的值。在 DFS 中,如果我们已经找到了一个,那么就可以直接终止搜索,因为该不可能比当前最小更小。如果 DFS 完成后仍然没有找到,那么说明该节点不连通,可以继续遍历其他节点。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值