URAL1004---Sightseeing trip (Floyed求最小环)

来源:互联网 发布:vender软件 编辑:程序博客网 时间:2024/06/06 05:43

【题目来源】:https://cn.vjudge.net/problem/URAL-1004
【题意】
给出n个点,m条双向边,赋权,问,在整个无向图中,最小环的路径。
什么是最小环呢,也就是从i点经过某些点重新回到i点的最小距离。
【思路】
最小环记录路径模板题。
给出两篇不错的讲解:求最小环讲解,以及最小环。
【代码】

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int INF=1e9;int w[110][110];int dis[110][110];int pre[110][110];int path[110];int num,minn,n,m;void floyed(){    for(int k=1;k<=n;k++)    {        for(int i=1;i<k;i++)        {            for(int j=i+1;j<k;j++)            {                int ans=dis[i][j]+w[j][k]+w[k][i];//最小环的总长度:i-->x1..x2..x3..xm-->j-->k-->i。                if(ans<minn)                {                    minn=ans;                    num=1;                    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++)//求i-->x1..x2..x3..xm-->j的最短路(不包括点k)        {            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[i][j]最初存的是i,pre[k][j]存的是k。                }            }        }    }}int main(){    while(~scanf("%d",&n))    {        if(n==-1) break;        scanf("%d",&m);        for(int i=1;i<=n;i++)        {            for(int j=1;j<=n;j++)            {                w[i][j]=w[j][i]=INF;                dis[i][j]=dis[j][i]=INF;                pre[i][j]=i;            }        }        for(int i=1;i<=m;i++)        {            int u,v,value;            scanf("%d%d%d",&u,&v,&value);            w[u][v]=w[v][u]=dis[u][v]=dis[v][u]=min(w[u][v],value);        }        minn=INF;        floyed();        if(minn==INF)        {            printf("No solution.\n");            continue;        }        for(int i=1;i<num;i++)        {            if(i!=1)printf(" ");            printf("%d",path[i]);        }        printf("\n");    }}
原创粉丝点击