POJ图论问题 ——Floyd算法汇集

学习Floyd算法中。。。。。。

Floyd  : 计算任意两节点间的最短距离,三重循环,效率较低!

POJ 1125   Stockbroker Grapevine                    http://poj.org/problem?id=1125

问题简述:一群股票经理人传递虚假消息,问从哪个人那里发出消息,可以使大家在最短的时间内都收到消息!

解法:先用floyd算法计算出每两个人之间传递消息的最短时间,然后,对每个人进行遍历,找出时间最短的哪个人!

问题的关键就是第i个人传递消息使所有人都能接受的时间,注意这个时间就是i个人发出消息,到最后一个人接受到消息的时间,不存在累加问题,这里我就陷入最短路的思维定势中;

当最后一个人接收到消息后其他所有人肯定已经接受到了!所以最后一个人接收到消息的时间就是第i个人传递消息花费的总时间!

POJ图论问题 ——Floyd算法汇集 View Code
 1 #include<iostream>

 2 #include<cstdio>

 3 #include<cstring>

 4 using namespace std;

 5 #define max 0xfffffff

 6 #define N 105

 7 int p[N][N];

 8 int n;

 9 void Floyd()

10 {

11     int i,j,k;

12     for(k=1;k<=n;k++)

13         for(i=1;i<=n;i++)

14             for(j=1;j<=n;j++)

15                 if(p[i][j]>p[i][k]+p[k][j])

16                     p[i][j]=p[i][k]+p[k][j];

17 }

18 

19 int main()

20 {

21     int i,j;

22     while(scanf("%d",&n)!=EOF)

23     {

24         if(n==0)  break;

25         for(i=1;i<=n;i++)

26             for(j=1;j<=n;j++)

27                 p[i][j]=max;

28         int c;

29         for(i=1;i<=n;i++)

30         {

31             scanf("%d",&c);

32             if(c==0) continue;//这里第一次,晕晕的用了次break,WA了两次

33             while(c--)

34             {

35                 int a,b;

36                 scanf("%d%d",&a,&b);

37                 if(p[i][a]>b)

38                     p[i][a]=b;

39             }

40 

41         }

42         Floyd();

43         int min=max;

44         int person;

45         for(i=1;i<=n;i++)

46         {

47             int temp=-1;

48             for(j=1;j<=n;j++)

49             {

50                 if(i!=j&&p[i][j]>temp)//注意这里要加上i!=j,或者在前边初始化时处理;

51                 temp=p[i][j];

52             }

53             if(temp<min)

54             {

55                 min=temp;

56                 person=i;

57             }

58         }

59         if(min==max)

60             printf("disjoint\n");

61         else

62             printf("%d %d\n",person,min);

63     }

64     return 0;

65 }

 

 

计算任意原点与目的地路径(可包含众多边)的最小边;

POJ 3615 Cow Hurdles     http://poj.org/problem?id=3615

POJ牛多啊!又一群牛啊!大意: 从A地到B地,中间不知道要过什么东东(单词不认识);反正需要跳,问从A到B最小的(必要)跳跃高度;

和昨晚做前天做的那个两个青蛙(http://www.cnblogs.com/heat-man/archive/2013/03/18/2966615.html 中Frogger)一样啊!只不过这个题有多次提问所以,Dijkstra估计要超时了!

这时就体现了Floyd的强大啊!

POJ图论问题 ——Floyd算法汇集 View Code
 1 #include<iostream>

 2 #include<cstring>

 3 #include<cstdio>

 4 using namespace std;

 5 #define N 305

 6 #define max 0xfffffff

 7 int p[N][N];

 8 int n,m,t;

 9 void Floyd()

10 {

11     int i,j,k;

12     for(k=1;k<=n;k++)

13         for(i=1;i<=n;i++)

14             for(j=1;j<=n;j++)

15             {

16                 if(p[i][j]>p[i][k]&&p[i][j]>p[k][j])

17                     p[i][j]=p[i][k]>p[k][j]?p[i][k]:p[k][j];

18             }

19 

20 }

21 

22 int main()

23 {

24     int i,j;

25     while(scanf("%d%d%d",&n,&m,&t)!=EOF)

26     {

27         for(i=1;i<=n;i++)

28             for(j=1;j<=n;j++)

29             {

30                 if(i==j)  p[i][j]=0;

31                 else p[i][j]=max;

32             }

33         int a,b,height;

34         for(i=1;i<=m;i++)

35         {

36             scanf("%d%d%d",&a,&b,&height);

37             if(p[a][b]>height)

38                 p[a][b]=height;

39         }

40         Floyd();

41         for(j=1;j<=t;j++)

42         {

43             int a,b;

44             scanf("%d%d",&a,&b);

45             if(p[a][b]==max)

46                 printf("-1\n");

47             else

48             printf("%d\n",p[a][b]);

49         }

50 

51     }

52     return 0;

53 }

54     

本题,是floyd的应用,根据题意修改了floyd循环内的东东,就ok了!

 

 

POJ 3264 Balance Lineup   http://poj.org/problem?id=3264

好吧!翘了英语听力写的这一题啊!还好题目是看懂了!估计是听不懂,呵呵!

刚开始时觉得,在Floyd中只要出现p[i][j]<p[i][k]+p[k][j]即可,测试结果不对;后来想通了,需要经过三层循环后,再次遍历一遍f[i][i]是否大于1;

初始值也不恰当,p[i][j]初始为了最大,最后修改为0;

(初始值根据题目的具体条件设置,如果求最小值,初始为最大,否则初始为最小,不然容易出现不易察觉的错误!)

POJ图论问题 ——Floyd算法汇集 View Code
 1 #include<iostream>

 2 #include<cstring>

 3 #include<string>

 4 #include<cstdio>

 5 #include<map>

 6 using namespace std;

 7 #define N 35

 8 #define max 0

 9 double  p[N][N];

10 map<string,int>money;

11 int n,m;

12 int flag;

13 int temp;

14 void Floyd()

15 {

16     int i,j,k;

17      for(k=1;k<=n;k++)

18         for(i=1;i<=n;i++)

19           for(j=1;j<=n;j++)

20           {

21               

22               if(p[i][j]<p[i][k]*p[k][j])

23               {

24                   p[i][j]=p[i][k]*p[k][j];

25                 

26               }

27               

28               

29           }

30 }

31 

32         

33 int main()

34 {

35     int i,j;

36     flag=1;

37     while(scanf("%d",&n)&&n)

38     {

39         money.clear();

40         for(i=1;i<=n;i++)

41             for(j=1;j<=n;j++)

42             {

43                 if(i==j)

44                     p[i][j]=1;

45                 else

46                 p[i][j]=max;

47             }

48         for(i=1;i<=n;i++)

49         {

50             string name;

51             cin>>name;

52             money[name]=i;

53         }

54         scanf("%d",&m);

55         for(i=1;i<=m;i++)

56         {

57             string s1,s2;

58             double fac;

59             cin>>s1;scanf("%lf",&fac);cin>>s2;

60             p[money[s1]][money[s2]]=fac;

61         }

62         

63         Floyd();

64         for(i=1;i<=n;i++)

65             if(p[i][i]>1) break;

66         if(i<=n)

67         printf("Case %d: Yes\n",flag++);

68         else

69             printf("Case %d: No\n",flag++);

70     }

71     return 0;

72 }

 

你可能感兴趣的:(floyd)