POJ 3660 && NYIST 211 Cow Contest && ZOJ 1060 Sorting It All Out【Floyd算法扩展应用】

来源:互联网 发布:谢朝阳 云计算 编辑:程序博客网 时间:2024/05/29 15:10

原文地址:http://blog.pureisle.net/archives/165.html

 

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)为图的距离矩阵,同时还可引入一个后继节点矩阵path来记录两点间的最短路径。

采用的是松弛技术,对在i和j之间的所有其他点进行一次松弛。所以时间复杂度为O(n^3);(由此可见Floyd算法不适合大规模数据、稀疏矩阵处理,比较适合小规模密集矩阵类的题目)

其状态转移方程如下: map[i,j]:=min{map[i,k]+map[k,j],map[i,j]}

map[i,j]表示i到j的最短距离

K是穷举i,j的断点

map[n,n]初值应该为0,或者按照题目意思来做。

当然,如果这条路没有通的话,还必须特殊处理,比如没有map[i,k]这条路

Floyd作为最短路算法众所周知,但是还有一些扩展性应用,比如可以根据元素间的某种关系建图,对图中的各个元素间的关系进行一个关系传递闭包。

 

题目来源:POJ 3660 Cow Contest

题意:n头牛 下面m行 每行x y 代表牛x打败了牛y 问有几头牛的最终排名是确定的

思路:传递闭包 如果x打败了y 令a[x][y]=1 并且a[y][x]=-1 其他不知道的都为0  然后floyd

最后对于每头牛数一下是否有n-1个1或者-1(就是不为0) 如果有n-1个不为0 说明该牛和其他牛都确定了状态

#include <cstdio>#include <algorithm>#include <queue>#include <vector>#include <map>#include <string>using namespace std;const int maxn = 110;int a[maxn][maxn];int n, m;void floyd(){for(int k = 1; k <= n; k++)for(int i = 1; i <= n; i++)for(int j = 1; j <= n; j++){if(a[i][k]  == -1  && a[k][j] == -1)a[i][j] = -1;if(a[i][k]  == 1  && a[k][j] == 1)a[i][j] = 1;}}int main(){scanf("%d %d", &n, &m);while(m--){int u, v;scanf("%d %d", &u, &v);a[u][v] = 1;//赢 a[v][u] = -1;//输 }floyd(); int ans = 0;for(int i = 1; i <= n; i++){int cnt = 0;for(int j = 1; j <= n; j++){if(i == j)continue;if(a[i][j])cnt++;}if(cnt == n-1){ans++;//printf("%d\n", i);}}printf("%d\n", ans);return 0;}


 

0 0
原创粉丝点击