Floyd算法 poj 3660

今天更Floyd算法,Floyd算法是求每对点之间的最短距离,只有5行的算法;

在图初始化的时候的d[i][i]=0,代表此点到此点的距离为0;其它点距离为无穷;

再上核心算法

for(int k = 1;k<=n;k++)
  for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++)
      if(d[i][j] < INF && d[k][j] < INF)
        d[i][j] = min(d[i][j], d[i][k] + d[k][j]);

有点类似动态规划的思想,拿或不拿,走或不走;第一个k循环是走1,2,3,。。。N-1个点的情况,也就是说,如果只走1个点可以到的距离的最短值,k=2是只走2个点位置能到达点的最短距离,INF是无穷大,代表次两点直接没有通路。下面两个循环就是N个点,思维还是蛮简单的,再看本题:

题目链接:http://poj.org/problem?id=3660

题目简介:

N头牛,如果A比B强,B比C强,则A必比C强

告知若干个强弱关系,问有多少牛的排名可以确定

这题就是Floyd的另外一种思维,只是考虑点的连通,那么在初始化的时候就可以用0来代表补连通,1来代表连通,最后在主算法中把 d[i][j] = min(d[i][j], d[i][k] + d[k][j]) 改成 的d[i][j] = d[i][j] || (d[i][k] && d[k][j]))代表ij之间有无通路,这样的结过成为传递闭包。

本题要判断可以找到关系位置的点,即此点的出度 + 此点的入度 = n-1,就可以比较出此点和其余任意点的位置关系;

分割线,上本题代码:


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int N,M;
int d[105][105];//邻接矩阵 
int main(){
	scanf("%d%d",&N,&M);
	memset(d,0,sizeof(d));
	while(M--){
		int a,b;
		scanf("%d%d", &a, &b);
		d[a][b] = 1;//a,b有关系 
	}
	//Floyd算法
	for(int k = 1; k <= N; ++ k)//只允许经过1,2,3.。。N个点 
	  for(int i = 1 ;i <= N;++ i)//N个点 
	     for(int j = 1; j <= N;++ j)
	      d[i][j] = d[i][j] || (d[i][k] && d[k][j]);//有关系 
	      
	    //判断度数 
		int l = 0,dg; 
		for(int i = 1; i <= N; i ++){
			dg = 0;
			for(int j = 1; j <= N; j ++){
				if(d[i][j] == 1 || d[j][i]==1)//ij有关系 
					dg ++;
			}
			if(dg == N-1)//出度加入度为n-1,说明找到了位置 
				l ++;
		}
		printf("%d\n",l); 
	return 0;
}

最后:

programming is the most fun you can have with your clothes on.

猜你喜欢

转载自blog.csdn.net/A_Pathfinder/article/details/81194076