• Floyd求最小环


    原理:不讲。

    模板如下。

     1 #include<cstdio>    
     2 #include<cstring>    
     3 #define find_min(a,b) a<b?a:b    
     4     
     5 const int N=109;    
     6 const int INF=0x7ffffff;    
    
     7 int f[N][N],dis[N][N],pre[N][N],path[N],n,m,num;  
     8     
     9 int main()    
    10 {    
    11         scanf("%d%d",&n,&m);
    12       
    13         for(int i=1;i<=n;i++)   
    14             for(int j=1;j<=n;j++) 
    15                 f[i][j]=dis[i][j]=INF,pre[i][j]=i;  
    16                 
    17         while(m--)
    18         {    
    19             int a,b,c;
    20             scanf("%d%d%d",&a,&b,&c);    
    21             f[a][b]=f[b][a]=dis[a][b]=dis[b][a]=find_min(f[a][b],c);    
    22         }    
    23     
    24         int min=INF;    
    25         for(int k=1;k<=n;k++)//最短路径外一点将最短路首尾链接,那么就得到一个最小环,枚举中间点  
    26         {  
    27             for(int i=1;i<k;i++)   
    28                 for(int j=i+1;j<k;j++)
    29                 {    
    30                     //求最小环不能用两点间最短路松弛,因为(i,k)之间的最短路,(k,j)之间的最短路可能有重合的部分    
    31                     //所以f[][]其实是不更新的,这里和单纯的floyd最短路不一样    
    32                     //dis[i][j]保存的是 i 到 j 的最短路权值和,(i->j)    
    33                     int tmp=dis[i][j]+f[i][k]+f[k][j];//这里k分别和i还有 j在f[][]中直接相连    
    34                     if(tmp<min)
    35                     {    
    36                         min=tmp;num=0;    
    37                         int p=j;    
    38                         while(p!=i)//回溯  
    39                         {  
    40                             path[num++]=p;    
    41                             p=pre[i][p];//pre[i][j]表示i->j最短路径上j前面的一个点    
    42                         }    
    43                         path[num++]=i; path[num++]=k;    
    44                     }    
    45                 }  
    46             
    47             for(int i=1;i<=n;i++)   
    48                 for(int j=1;j<=n;j++)   
    49                     if(dis[i][j]>dis[i][k]+dis[k][j])
    50                     {    
    51                         dis[i][j]=dis[i][k]+dis[k][j];//dis[][]保存两点间最短距离    
    52                         pre[i][j]=pre[k][j];    
    53                     }    
    54                 
    55         }    
    56         if(min==INF)puts("No solution.");    
    57         else
    58         {    
    59             printf("%d",path[0]);    
    60             for(int i=1;i<num;i++)    
    61                 printf(" %d",path[i]);    
    62             puts("");    
    63         }  
    64     return 0;    
    65 }    
    View Code


    例题:POJ 1734 Sightseeing trip

              HDU    1599     find the mincost route

             

  • 相关阅读:
    此刻,很想那些老朋友
    985工程介绍
    211工程介绍
    蓝牙耳机声音断断续续
    不支持用淋浴洗澡
    在HY买饭
    成长路上的六个W
    屎、洗脚水
    Ubuntu更换软件源
    视频流媒体服务器RTMP和RTSP区别是什么?如何区分?
  • 原文地址:https://www.cnblogs.com/adelalove/p/8486680.html
Copyright © 2020-2023  润新知