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 }