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 }

 

posted @ 2012-04-14 15:37  知行执行  阅读(154)  评论(0编辑  收藏  举报