• 算法复习——floyd求最小环(poj1734)


    题目:

    题目描述

    N 个景区,任意两个景区之间有一条或多条双向的路来连接,现在 Mr.Zeng 想找一条旅游路线,这个路线从A点出发并且最后回到 A 点,假设经过的路线为 V1,V2,....VK,V1,那么必须满足 K>2,就是说至除了出发点以外至少要经过 2 个其他不同的景区,而且不能重复经过同一个景区。不存在这样的景区X:从 X 出发不到达其他景区马上回到 X。现在 Mr.Zeng 需要你帮他找一条这样的路线,并且长度越小越好。

    输入格式

    第一行包含两个正整数:景区个数 N (N<=100),另一个是道路的数目 M (M<10000)。
    接下来 M 行每行描述一条路,每一行有三个正整数 A,B,C,其中 A 和 B 分别表示这条路连接的两个景区的编号,C 表示这条路的长度(不超过 500 的正整数)。

    输出格式

    如果这条观光路线是不存在的话就显示“No solution.”(有句号);
    如果这条观光路线存在就输出经过的最小长度。

    样例数据 1

    输入  [复制]

     
    5 7 
    1 4 1 
    1 3 300 
    3 1 10 
    1 2 16 
    2 3 100 
    2 5 15 
    5 3 20

    输出

    61

    备注

    【样例说明】
    经过路线 1 3 5 2 1,长度:10+20+15+16=61

    题解:

      floyd求最小环模板题···

      简单来说···为了保证floyd求最小环时为了保证不会出现重边的错误,在求最短路时,枚举k,先找经过了k的一段最短路,再与对应的已经求出的最短路相加···就可以保证不会重边了···

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<ctime>
    #include<cctype>
    #include<cstring>
    #include<string>
    #include<algorithm>
    using namespace std;
    const int inf=1e+8;
    const int N=105;
    const int M=10005;
    int n,m,dis[N][N],dp[N][N];
    int R()
    {
      char c;
      int f=0;
      for(c=getchar();c<'0'||c>'9';c=getchar());
      for(;c>='0'&&c<='9';c=getchar())
        f=(f<<3)+(f<<1)+c-'0';
      return f;
    }
    int floyd()
    {
      int minn=inf;
      for(int k=1;k<=n;k++)
      {
        for(int i=1;i<k;i++)
          for(int j=i+1;j<k;j++)
            minn=min(dp[i][j]+dis[i][k]+dis[k][j],minn);
        for(int i=1;i<=n;i++)
          for(int j=1;j<=n;j++)
            dp[i][j]=min(dp[i][k]+dp[k][j],dp[i][j]);
          
      }
      return minn;
    }
    int main()
    {
      //freopen("a.in","r",stdin);
      n=R();  
      m=R();
      for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
          dis[i][j]=dp[i][j]=inf;
        
      int a,b,c;
      for(int i=1;i<=m;i++)
      {
        a=R();
        b=R();
        c=R();
        dis[a][b]=dis[b][a]=dp[a][b]=dp[b][a]=min(dis[a][b],c);
      }
      int ans; 
      ans=floyd();
      if(ans==inf)
        cout<<"No solution."<<endl;
      else
        cout<<ans<<endl;
      return 0;
    }
  • 相关阅读:
    Java基础(六)判断两个对象相等:equals、hashcode、toString方法
    同时找最大最小值
    0-1背包问题
    大数相加
    单例模式(singleton pattern)
    House Robber
    Binary Tree Paths
    双向链表的插入
    工厂模式(factory pattern)
    装饰者模式(decorator pattern)
  • 原文地址:https://www.cnblogs.com/AseanA/p/7399464.html
Copyright © 2020-2023  润新知