zoukankan      html  css  js  c++  java
  • poj 1734 (最小环)

    floyd的核心思想就是动态规划从k=0->n来松弛i->j的路径,

    因为floyd的外层到k时,i->j的最短路上肯定没有k。所以我们可以先找环,再更新。如果存在的话,那么肯定是i->j  然后j->k->i。这样保证了i->j这条路不经过k。

    View Code
     1 // File Name: 1734.cpp
     2 // Author: Missa
     3 // Created Time: 2013/2/7 星期四 16:39:58
     4 
     5 #include<cstdio>
     6 #include<cstring>
     7 using namespace std;
     8 
     9 const int inf = 100000000;
    10 const int maxn = 110;
    11 int n,m,num;
    12 int dis[maxn][maxn];
    13 int path[maxn][maxn];
    14 int g[maxn][maxn];
    15 int res[maxn];
    16 
    17 void dfs(int i,int j)
    18 {
    19     int k=path[i][j];
    20     if(k==0)
    21     {
    22         res[num++]=j;
    23         return ;
    24     }
    25     dfs(i,k);
    26     dfs(k,j);
    27 }
    28 
    29 int main()
    30 {
    31     while(~scanf("%d%d",&n,&m))
    32     {
    33         for(int i=1;i<=n;i++)
    34         {
    35             for(int j=i+1;j<=n;j++)
    36                 g[i][j]=g[j][i]=dis[i][j]=dis[j][i]=inf;
    37             g[i][i]=dis[i][i]=0;
    38         }
    39         for(int i=0;i<m;i++)
    40         {
    41             int x,y,z;
    42             scanf("%d%d%d",&x,&y,&z);
    43             if(z<g[x][y])
    44             {
    45                 dis[x][y]=dis[y][x]=z;
    46                 g[x][y]=g[y][x]=z;
    47             }
    48         }
    49         int ans=inf;
    50         memset(path,0,sizeof(path));
    51         for(int k=1;k<=n;k++)
    52         {
    53             for(int i=1;i<k;i++)
    54                 for(int j=i+1;j<k;j++)//求环
    55                     if(dis[i][j] +g[i][k]+g[k][j] <ans)
    56                     {
    57                         ans=dis[i][j]+g[i][k]+g[k][j];
    58                         num=0;
    59                         res[num++]=i;
    60                         dfs(i,j);
    61                         res[num++]=k;
    62                     }
    63             for(int i=1;i<=n;i++)
    64                 for(int j=1;j<=n;j++)
    65                     if(dis[i][k]+dis[k][j]<dis[i][j])//松弛
    66                     {
    67                         dis[i][j]=dis[i][k]+dis[k][j];
    68                         path[i][j]=k;
    69                     }
    70         }
    71         if(ans==inf)
    72             puts("No solution.");
    73         else
    74         {
    75             printf("%d",res[0]);
    76             for(int i=1;i<num;i++)
    77                 printf(" %d",res[i]);
    78             printf("\n");
    79         }
    80     }
    81     return 0;
    82 }
  • 相关阅读:
    I
    H
    装箱问题
    E
    Oracle创建视图(View)
    (转)Navicat Premium 12.1.8.0安装与激活
    bigdecimal 保留小数位
    用命令修改Oracle数据库密码
    sql中exists,not exists的用法
    在Orcl中通过SQL语句修改创建表
  • 原文地址:https://www.cnblogs.com/Missa/p/2908903.html
Copyright © 2011-2022 走看看