URAL

来源:互联网 发布:网络负面的影响 编辑:程序博客网 时间:2024/06/07 14:43

Sightseeing Trip

题目链接:Sightseeing Trip

题意:给你一个无向有环图,有n个点,m条边(可能有重边),问图中的最小环是多少,打印出最小环

思路:
一种方法是:对于每一个(u,v),去掉(u,v)这条边,然后最短路跑一遍计算出u到v的最短距离s,s+dis[u][v]就是环的长度,遍历找出最小环即可

另一种方法是:在用Floyd()松弛之前,对于当前的每一个k,都可以看成存在以k为起点和终点的环(k点为环中最大的点),并且环中的所有边都没有被k松弛过。
那么对于每一个k点,只需要先寻找k的最小环再松弛即可

代码:

#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;const int inf=1e8;//注意inf不能过大,否则会爆intconst int maxn=105;int dis[maxn][maxn],mp[maxn][maxn],path[maxn],pre[maxn][maxn];//dis表示松弛的图,mp表示原图,pre记录前面的点int n,m,minx,tot;void Floyd(){    minx=inf;    for(int k=1; k<=n; ++k)    {        for(int i=1; i<k; ++i)            for(int j=i+1; j<k; ++j)            {                if(dis[i][j]+mp[i][k]+mp[k][j]<minx)                {                    minx=dis[i][j]+mp[i][k]+mp[k][j];                    tot=0;                    int tmp=j;                    path[tot++]=j;                    while(tmp!=i)                    {                        tmp=pre[i][tmp];                        path[tot++]=tmp;                    }                    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];                    pre[i][j]=pre[k][j];//注意pre的写法                }    }}void init(){    for(int i=1; i<=n; ++i)        for(int j=1; j<=n; ++j)        {            dis[i][j]=mp[i][j]=inf;            pre[i][j]=i;        }}int main(){    while(scanf("%d",&n)&&(n+1))    {        init();        scanf("%d",&m);        int u,v,w;        for(int i=1; i<=m; ++i)        {            scanf("%d%d%d",&u,&v,&w);            if(w<mp[u][v])                mp[u][v]=mp[v][u]=dis[u][v]=dis[v][u]=w;        }        Floyd();        if(minx==inf)            printf("No solution.\n");        else        {            for(int i=0; i<tot-1; ++i)                printf("%d ",path[i]);            printf("%d\n",path[tot-1]);        }    }    return 0;}