zoukankan      html  css  js  c++  java
  • Codevs 2611 观光旅游(floyed最小环)

    2611 观光旅游
    时间限制: 1 s
    空间限制: 128000 KB
    题目等级 : 钻石 Diamond
    题目描述 Description
    某旅游区里面有N个景点。两个景点之间可能直接有道路相连,用a[i][j]表示它的长度,否则它们之间没有直接的道路相连。这里所说的道路是没有规定方向的,也就是说,如果从i到j有直接的道路,那么从j到i也有,并且长度与之相等.旅游区规定:每个游客的旅游线路只能是一个回路(好霸道的规定)。也就是说,游客可以任取一个景点出发,依次经过若干个景点,最终回到起点。一天,Smart决定到这个景区来旅游,由于他实在已经很累了,于是他决定尽量少走一些路.他想请你帮他求出最优的路线。怎么样,不是很难吧?
    输入描述 Input Description
    输入有多组数据。对于每组数据:
    第一行有两个正整数N,M,分别表示景点个数和有多少对景点之间直接有边相连(N≤100,M≤10000);
    接下来M行,每行三个正整数,分别表示一条道路的两端的编号,以及这条道路的长度(长度≤1000)。
    输出描述 Output Description
    对于每组数据,输出一行,如果该回路存在,则输出一个正整数,表示该回路的总长度;否则输出“No solution.”(不要输出引号)
    样例输入 Sample Input
    5 7
    1 4 1
    1 3 300
    3 1 10
    1 2 16
    2 3 100
    2 5 15
    5 3 20
    4 3
    1 2 10
    1 3 20
    1 4 30
    样例输出 Sample Output
    61
    No solution.
    数据范围及提示 Data Size & Hint
    N≤100,M≤10000
    长度≤1000
    分类标签 Tags
    最短路 图论

    /*
    floyed最小环问题.
    我们枚举一条不经过K点的路径.
    那么一开始可能是无解的.
    然后随着k点的增大,环的长度随之有解.
    这也迎合了floyed的DP思想.
    ans就是每条路径的起点和终点间的边权值+起点和终点的最小距离.
        即ans=min(ans,a[i][j]+g[i][k]+g[k][j]).
    然后为什么环的更新要放在原floyed的后面呢?
      我认为是k点不能==i点,放在后面的话因为k已经更新,
      所以现在a[i][j]理应是要更新的,但是放后面的话i是要循环到k的不好操作. 
      所以我们用上一个k点更新答案. 
    望路过大神赐教orz. 
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define MAXN 101
    using namespace std;
    int g[MAXN][MAXN],n,m,a[MAXN][MAXN],ans;
    void floyed()
    {
        for(int k=1;k<=n;k++)
        {
          for(int i=1;i<k;i++)
              for(int j=i+1;j<k;j++)
                  ans=min(ans,a[i][j]+g[i][k]+g[k][j]);
          for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
              a[i][j]=min(a[i][j],a[i][k]+a[k][j]);
        }
    }
    int main()
    {
        while(scanf("%d %d",&n,&m)!=EOF)
        {
            int x,y,z;
            memset(g,127/3,sizeof(g));
            memset(a,127/3,sizeof(a));
            ans=g[0][0];
            for(int i=1;i<=n;i++)
              a[i][i]=g[i][i]=0;
            for(int i=1;i<=m;i++)
            {
                scanf("%d%d%d",&x,&y,&z);
                a[x][y]=g[x][y]=min(g[x][y],z);
                a[y][x]=g[y][x]=g[x][y];
            }
            floyed();
            if(ans==g[0][0])  printf("No solution.
    ");
            else printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    进程和线程的区别?什么时候用进程?什么时候用线程?----看到好的复制到自己的园子里哈哈
    HTTPS详细讲解一篇就够了
    MySQL存储过程
    Spring注入全局的HttpServletRequest
    Java进阶必备
    Java8新特性
    java.time包常用类API学习记录
    Maven常用插件
    maven-dependency-versions-check-plugin, Maven 插件查找依赖版本冲突
    Jackson自定义注解
  • 原文地址:https://www.cnblogs.com/nancheng58/p/6070761.html
Copyright © 2011-2022 走看看