10048 - Audiophobia (Floyd)

该题是Floyd算法的一个巧妙变形,虽然AC率很高,但是真正要灵活变化到做出该题,显然要明白Floyd算法的思想和原理 ,弄清楚为什么可以这样更改算法的核心部分。

Floyd算法其实利用了动态规划的思想,适合求解结点不是很多的稠密图 。

我们都知道,动态规划在利用循环嵌套求解时是要规定一个次序的,这样才能将状态成功的转移 。该题的次序就是由k来定义的,从小到大枚举k,定义其意义为i和j之间一点。

那么对于每一个i和j以及每一个k,最优状态就的状态转移方程d[i][j] = min(d[i][j],d[i][k]+d[k][j]);

为什么这样可以表示出每两个点之间的最短路呢? 我们不妨将最短路看成动归中的最优解,那么每一个状态的最优解都是从局部最优解转移过来的,每一个状态都具有相似的子结构 ,所以就可以动态规划出所有的最优解了。

既然知道了其思想核心的动态规划,那么就不难修改了,修改时要注意状态方程所表示的新意义以及状态的转移 。

该题是求最大噪音最小的路径,是不是有点眼熟 ? 没错 ! 还记得第九章例题:《最大面积最小的三角剖分》吗? 如果忘了可以看这里:点击打开链接

该题的思想和那道题如出一辙,所以状态方程即可写出:d[i][j] = min(d[i][j],max(d[i][k],d[k][j]));

细节参见代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 100 + 5;
const int INF = 100000000;
int n,m,a,b,c,q,d[maxn][maxn],kase = 0,ok = 0;
void init() {
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++) d[i][j] = INF;
    for(int i=1;i<=m;i++) {
        scanf("%d%d%d",&a,&b,&c);
        d[a][b] = d[b][a] = c;
    }
}
void Floyd() {
    for(int k=1;k<=n;k++)
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            if(d[i][k]!=INF&&d[k][j]!=INF)
            d[i][j] = min(d[i][j],max(d[i][k],d[k][j]));
}
int main() {
    while(~scanf("%d%d%d",&n,&m,&q)) {
        if(!n && !m && !q) return 0;
        if(ok) printf("\n");
        else ok = 1;
        init();
        Floyd();
        printf("Case #%d\n",++kase);
        while(q--) {
            scanf("%d%d",&a,&b);
            if(d[a][b] == INF) printf("no path\n");
            else printf("%d\n",d[a][b]);
        }
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-10 04:57:13

10048 - Audiophobia (Floyd)的相关文章

Uvaoj 10048 - Audiophobia(Floyd算法变形)

1 /* 2 题目大意: 3 从一个点到达另一个点有多条路径,求这多条路经中最大噪音值的最小值! . 4 5 思路:最多有100个点,然后又是多次查询,想都不用想,Floyd算法走起! 6 */ 7 #include<iostream> 8 #include<cstring> 9 #include<cstdio> 10 #define INF 0x3f3f3f3f 11 using namespace std; 12 13 int map[105][105]; 14 1

uva 10048 - Audiophobia(floyd 的变形)

给出一个无向连通图以及边权,目的求从一个点到另一个点的路径中 边权最大值 最小的那条路径,输出的是该条路径的最大边权. 因为是两点间路径问题,且数据量很小(只有100个) ,所以考虑使用floyd算法. 但是要求的并不是传统 floyd 所求的 两点之间最短路 问题,但是通过理解floyd算法的原理,可以发现floyd的思想可以用来解决这种问题: 对于任何一条至少包含两条边的路径i->j,一定存在一个中间点k,使得i->j的总长度等于i->k与k->j的长度之和.因为路径可能有多个

UVA - 10048 Audiophobia (Floyd应用)

题意:求出两点之间所有路径最大权值的最小值. 思路:转变一下Floyd的形式即可: 注意:注意初始化问题,还有UVA奇葩的输出形式. 代码如下: #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<map> using namespace std; #define inf 0x3f3f3f int dp[110][110]; int mai

【UVA】821-Page Hopping(Floyd)

模板题,求一个点到任何一点的距离,用Floyd就行了,结点不一定是从1 ~ n 的,所以需要记录结点的id 14063895 821 Page Hopping Accepted C++ 0.119 2014-08-19 10:00:27 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<vector> #include<sta

hdu 1690 Bus System(Floyd)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1690 Problem Description Because of the huge population of China, public transportation is very important. Bus is an important transportation method in traditional public transportation system. And it's

人活着系列之开会 (floyd)

人活着系列之开会 Time Limit: 1000MS Memory limit: 65536K 题目描述 人活着如果是为了事业,从打工的到老板的,个个都在拼搏,奋斗了多年终于有了非凡成就,有了一笔丰富的钱财.反过来说,人若赚取了全世界又有什么益处呢?生不带来,死了你还能带去吗?金钱能买保险,但不能买生命,金钱能买药品,但不能买健康,人生在世,还是虚空呀! 在苍茫的大海上,有很多的小岛,每个人都在自己的小岛上.又到了开会的时候了,鹏哥通过飞信告知了每个人,然后大家就开始往鹏哥所在的主岛走,问谁先

hdu 1869 (Floyd)

http://acm.hdu.edu.cn/showproblem.php?pid=1869 六度分离 Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4355    Accepted Submission(s): 1768 Problem Description 1967年,美国著名的社会学家斯坦利·米尔格兰姆提出了一个名为“小世界现象

最短路径之弗洛伊德算法(Floyd)

Floyd算法又称为插点法,是一种用于寻找给定的加权图中多源点之间最短路径的算法. 路径矩阵 通过一个图的权值矩阵求出它的每两点间的最短路径矩阵. 从图的带权邻接矩阵A=[a(i,j)] n×n开始,递归的进行n次更新,即由矩阵D(0)=A,按一个公式,构造出矩阵D(1): 又用同样地公式由D(1)构造出D(2):--:最后又用同样的公式由D(n-1)构造出矩阵D(n).矩阵D(n) 的 i 行 j 列元素便是 i 号顶点到 j 号顶点的最短路径长度,称D(n)为图的距离矩阵,同时还可引入一个后

(floyd)佛洛伊德算法

Floyd–Warshall(简称Floyd算法)是一种著名的解决任意两点间的最短路径(All Paris Shortest Paths,APSP)的算法.从表面上粗看,Floyd算法是一个非常简单的三重循环,而且纯粹的Floyd算法的循环体内的语句也十分简洁.我认为,正是由于“Floyd算法是一种动态规划(Dynamic Programming)算法”的本质,才导致了Floyd算法如此精妙.因此,这里我将从Floyd算法的状态定义.动态转移方程以及滚动数组等重要方面,来简单剖析一下图论中这一重