Getting in Line |
题目链接:
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=108&page=show_problem&problem=152
题目比较典型,给你n个点的坐标,找出一条连接所有点的最短的路径,并且求出此时每两个点之间的路径长度,是跟前天校赛最后一题的题目类似,当时听题解时说是二分图匹配,我想这题也可以用二分图匹配吧?但还是用了当初的做法,可以用深度查找(回溯),或者用上排列,我纳闷为什么一开始我会认为是最小生成树呢?汗!!根本是不沾边的事情啊,尽管知道怎么做,但还是调试了一段时间啊
排列做法:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<iomanip> 6 #include<algorithm> 7 #define MAXN 10 8 #define MAX_VALUE 21474836 9 using namespace std; 10 typedef struct dot{ 11 int x, y; 12 }dot; 13 dot maze[MAXN]; 14 double len[MAXN] , last_len[MAXN]; 15 int list[MAXN], last_list[MAXN]; 16 double cal_dis(int i, int j) 17 { 18 return sqrt((double)((maze[i].x-maze[j].x)*(maze[i].x-maze[j].x)+(maze[i].y-maze[j].y)*(maze[i].y-maze[j].y))); 19 } 20 int main() 21 { 22 23 int T=0; 24 int n; 25 while(cin>>n && n) 26 { 27 for(int i=0; i<n; ++i) 28 cin>>maze[i].x>>maze[i].y; 29 for(int i=0; i<n; ++i) list[i] = i; 30 double max = MAX_VALUE; 31 do 32 { 33 double ans = 0; 34 len[0] = 0; 35 for(int i=1; i<n; ++i) 36 { 37 len[i] = cal_dis(list[i-1], list[i])+16; 38 39 ans += len[i]; 40 } 41 if(max > ans) 42 { 43 max = ans; 44 memcpy(last_list, list, sizeof(int)*n); 45 for(int i=1; i<n; ++i) last_len[i] = len[i]; 46 } 47 }while(next_permutation(list, list+n)); 48 printf("**********************************************************\nNetwork #%d\n", ++T); 49 for(int i=1; i<n; ++i) 50 { 51 printf("Cable requirement to connect (%d,%d) to (%d,%d) is %.2lf feet.\n", 52 maze[last_list[i-1]].x, maze[last_list[i-1]].y, maze[last_list[i]].x, maze[last_list[i]].y, last_len[i]); 53 } 54 printf("Number of feet of cable required is %.2lf.\n", max); 55 } 56 return 0; 57 }
深度查找(回溯):
1 #include<stdio.h> 2 #include<string.h> 3 #include<math.h> 4 #define MAXN 10 5 double maze[MAXN][MAXN], road[MAXN]; 6 int x[MAXN], y[MAXN]; 7 int visit[MAXN]; 8 int record[MAXN], reco[MAXN]; 9 double final[MAXN]; 10 double max; 11 double calcu_dis(int x1, int y1, int x2, int y2) 12 { 13 int temp = (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2); 14 return sqrt((double)temp); 15 } 16 17 void dfs(int n, int last, int cur) 18 { 19 int i, j; 20 double sum = 0; 21 if(cur == n) 22 { 23 for(j=0; j<n; ++j) 24 { 25 sum += road[j]; 26 } 27 if(sum < max) 28 { 29 max = sum; 30 for(j=0; j<n; ++j) 31 final[j] = road[j], reco[j] = record[j]; 32 } 33 return; 34 } 35 for(i=0; i<n; ++i) 36 { 37 if(!visit[i]) 38 { 39 visit[i] = 1; 40 record[cur] = i; 41 road[cur] = calcu_dis(x[last], y[last], x[i], y[i]); 42 dfs(n, i, cur+1); 43 visit[i] = 0; 44 } 45 } 46 return; 47 } 48 49 int main() 50 { 51 52 int i, j, n, T=1; 53 while(scanf("%d", &n) != EOF && n) 54 { 55 max = 21474836; 56 for(i=0; i<n; ++i) 57 scanf("%d%d", &x[i], &y[i]); 58 memset(visit, 0, sizeof(visit)); 59 for(i=0; i<n; ++i) 60 { 61 visit[i] = 1; 62 record[0] = i; 63 road[0] = 0; 64 dfs(n, i, 1); 65 visit[i] = 0; 66 } 67 68 printf("**********************************************************\nNetwork #%d\n", T++); 69 for(i=1; i<n; ++i) 70 { 71 printf("Cable requirement to connect (%d,%d) to (%d,%d) is %.2lf feet.\n", 72 x[reco[i-1]], y[reco[i-1]], x[reco[i]], y[reco[i]], final[i]+16); 73 } 74 printf("Number of feet of cable required is %.2lf.\n", max+(n-1)*16); 75 } 76 return 0; 77 }