【最短路】Vijos P1046 观光旅游
题目链接:
题目大意:
给n个点(n<=100),m条无向边(m<=10000),问这张图的最小环长度。
(注意:无自环,同一个点对之间的多条路最终只算作1条而不是2个点的环,被这里坑了一次)
题目思路:
【最短路】
无向图最小环问题。
有向图最小环的长度为2,但是这题因为是无向图,所以环的长度至少为3。所以可以枚举k为中间点,求i到j不经过k的最短路最后加上Di,k和Dk,j即为答案。
用floyd,时间复杂度是O(n3).
1 // 2 //by coolxxx 3 // 4 #include<iostream> 5 #include<algorithm> 6 #include<string> 7 #include<iomanip> 8 #include<memory.h> 9 #include<time.h> 10 #include<stdio.h> 11 #include<stdlib.h> 12 #include<string.h> 13 #include<stdbool.h> 14 #include<math.h> 15 #define min(a,b) ((a)<(b)?(a):(b)) 16 #define max(a,b) ((a)>(b)?(a):(b)) 17 #define abs(a) ((a)>0?(a):(-(a))) 18 #define lowbit(a) (a&(-a)) 19 #define sqr(a) ((a)*(a)) 20 #define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b)) 21 #define eps 1e-8 22 #define J 10000 23 #define MAX 0x7f7f7f7f 24 #define PI 3.1415926535897 25 #define N 104 26 using namespace std; 27 int n,m,lll,ans,cas; 28 int map[N][N],f[N][N]; 29 void floyd() 30 { 31 int i,j,k; 32 for(k=1;k<=n;k++) 33 { 34 for(i=1;i<k;i++) 35 { 36 if(map[i][k]==MAX)continue; 37 for(j=i+1;j<k;j++) 38 { 39 if(map[k][j]==MAX || f[i][j]==MAX)continue; 40 cas=f[i][j]+map[i][k]+map[k][j]; 41 ans=min(ans,cas); 42 } 43 } 44 for(i=1;i<=n;i++) 45 { 46 if(f[i][k]==MAX || i==k)continue; 47 for(j=1;j<=n;j++) 48 if(f[k][j]!=MAX && i!=j && j!=k) 49 f[i][j]=min(f[i][j],f[i][k]+f[k][j]); 50 } 51 } 52 } 53 int main() 54 { 55 #ifndef ONLINE_JUDGE 56 // freopen("1.txt","r",stdin); 57 // freopen("2.txt","w",stdout); 58 #endif 59 int i,j,k,x,y,z; 60 // while(~scanf("%s",s1)) 61 while(~scanf("%d",&n)) 62 { 63 memset(map,0x7f,sizeof(map)); 64 scanf("%d",&m); 65 ans=MAX; 66 for(i=1;i<=m;i++) 67 { 68 scanf("%d%d%d",&x,&y,&z); 69 map[y][x]=map[x][y]=min(map[x][y],z); 70 } 71 memcpy(f,map,sizeof(map)); 72 floyd(); 73 if(ans!=MAX)printf("%d\n",ans); 74 else puts("No solution."); 75 } 76 return 0; 77 } 78 79 80 /* 81 // 82 83 // 84 */