HDOJ 4034

View Code
 1 /*

 2 最短路:

 3 floyd倒着用

 4 优秀代码中这样判断

 5 若: path[i][j]>path[i][k]+path[k][j]则 这不是  最短路  是 impossible 

 6 若:path[i][j]==path[i][k]+path[k][j]  则 从 i到 j 用不着直接路径 

 7 */

 8 #include<iostream>

 9 #include<cstdio>

10 #include<cstring>

11 using namespace std;

12 

13 int path[105][105];

14 bool flag[105][105];

15 int edge=0;

16 int n;

17 bool f;

18 

19 void slove()

20 {

21   int i,j,ti,tj;

22   int min;

23   int num=n*n-n;

24   memset(flag,0,sizeof(flag));

25   while(num>0)

26   {

27    min=1000010;  

28    ti=0;

29    tj=0;     

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

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

32     {

33       if(i==j)continue;

34       if(path[i][j]<min && flag[i][j]==0)

35        {

36          min=path[i][j];

37          ti=i;

38          tj=j;

39        }

40     }

41    if(ti&&tj)

42     {

43       flag[ti][tj]=1;

44        num--;

45        edge++;

46     }

47    if(ti==0 || tj==0)return ;

48   

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

50      {

51        if(i==ti || i==tj)continue;          

52        if(path[i][ti]+path[ti][tj]==path[i][tj])

53        {

54         if(flag[i][tj]==0) num--;//注意  对于  ti 不同的  ,tj相同的这种情况  [i][tj]可能多次出现 

55         flag[i][tj]=1;

56          if(num<=0)break;

57        }

58        else

59        {          

60          if((path[i][ti]+path[ti][tj])<path[i][tj])

61          {

62            f=1;

63            return ;

64          }

65        }

66      }

67    } 

68 }

69 

70 int main()

71 {

72   int t,k,i,j;

73   scanf("%d",&t);

74   for(k=1;k<=t;++k)

75    {

76      scanf("%d",&n);

77      f=0;

78      edge=0;

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

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

81       {

82        scanf("%d",&path[i][j]);

83       }

84         

85      slove();

86      

87      printf("Case %d: ",k);

88      if(f)printf("impossible\n");

89      else printf("%d\n",edge);

90    }

91   return 0;

92 }

优秀代码:

View Code
 1 #include<iostream>

 2 #include<cstdio>

 3 #include<cstring>

 4 using namespace std;

 5 const int inf=1<<30;

 6 const int nMax=105;

 7 int map[nMax][nMax];

 8 bool vis[nMax][nMax];

 9 int main(){

10     int t,n,num,i,j,k,flag,cas=0;

11     scanf("%d",&t);

12     while(t--){

13         cas++;

14         flag=num=0;

15         scanf("%d",&n);

16         memset(vis,0,sizeof(vis));

17         for(i=1;i<=n;i++){

18             for(j=1;j<=n;j++){

19                 scanf("%d",&map[i][j]);

20                 if(!map[i][j])map[i][j]=inf;

21                 else{

22                     num++;

23                 }

24             }

25         }

26         for(k=1;k<=n;k++){

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

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

29                     if(flag||map[i][j]==inf||map[i][k]==inf||map[k][j]==inf)continue;

30                     if(map[i][j]>map[i][k]+map[k][j]){

31                         flag=1;

32                     }

33                     if(map[i][j]==map[i][k]+map[k][j]){

34                         if(!vis[i][j])num--;

35                         vis[i][j]=1;

36                     }

37                 }

38             }

39         }

40         printf("Case %d: ",cas);

41         if(flag)printf("impossible\n");//cout<<"impossible\n";

42         else{

43             printf("%d\n",num);

44         }

45     }

46     return 0;

47 }

 

你可能感兴趣的:(OJ)