10072. 「一本通 3.2 例 1」Sightseeing Trip

题意:给你一个n个点加权无向图,要你从里面找一个路径最短的环,每个点只能经过一次 ,如果存在这样的最短环则把路径给打印出来,如果有多个,打印一个出来即可。
本题的重点是,如果用简单的用floyd求最小环,你会发现在求最短路的过程中有很多点是重复经过的。现在的问题是怎么找没有重复经过同一个点的最小环,每次修改最小环是都记录下当前的path
我们可以做一个限制 就是k比i,j都大,假如说求u->i->j->k->v的,最小环,如果u k v都确定的情况下,只需要找通过i j的最小路程,现在要保证,k与之前的i,j不相同,所以需要设置k比i,j都大,这道题的难点解决了
还有一点就是本题输出用了一点二分的思想,递归每次找i到k和k到j两个区间
AC代码

#include<stdio.h>
#include<bits/stdc++.h>
using namespace std;
const int N=105;
#define inf 0x3f3f3f
typedef long long ll;
int h[N][N],d[N][N];
int pos[N][N];
int path[N],cnt;
void getpath(int i,int j)
{
    if(!pos[i][j])
        return ;
    int k=pos[i][j];
    getpath(i,k);
    path[cnt++]=k;
    getpath(k,j);
}
int main()
{
    memset(h,inf,sizeof(h));
    int m,n;
    scanf("%d%d",&n,&m);
    while(m--)
    {
        int u,v,w;
        scanf("%d%d%d",&u,&v,&w);
        h[u][v]=h[v][u]=min(h[u][v],w);
    }
    memcpy(d,h,sizeof(h));
    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++)
            {
                if((ll)d[i][j]+h[i][k]+h[k][j]<res)
                {
                    res=d[i][j]+h[i][k]+h[k][j];
                    cnt=0;
                    path[cnt++]=k;
                    path[cnt++]=i;
                    getpath(i,j);
                    path[cnt++]=j;
                }
            }
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                if(d[i][j]>d[i][k]+d[k][j])
                {
                    d[i][j]=d[i][k]+d[k][j];
                    pos[i][j]=k;
                }
            }
        }
    }
    if(res>=inf)
        printf("No solution.\n");
    else
    {
        for(int i=0;i<cnt;i++)
            printf("%d ",path[i]);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值