【题目】
找朋友
【题意】
找朋友:已知一组人名对,他们互为朋友关系,输入一个人名对,找到两个人认识的最短关系路径
例如:<Mike, Lucy>, <Mike, Jack>, <Jack, Amy>, <Amy, Sean>, <Lucy, Amy>, <Lucy, Sean>
输入:<Mike, Sean>
输出:Mike,Lucy,Sean
注意:1. 两个人可能无法建立朋友关联。 2. 如果同时存在两条最短路径,只要任意输出一组。
【题解】
1、首先Flody处理图中任意两点的距离。
2、然后通过 dis( A->B ) + dis( B->C ) == dis( A -> C ) 作为依据来处理是否必经B点。
3、利用(2)进行dfs搜索,最后打印路径
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<vector> 5 #include<string> 6 #include<map> 7 using namespace std; 8 9 const int N = 1e3 + 10 ; 10 map< string , int > Name2num ; 11 map< int , string > Num2name ; 12 vector< vector<int> > G; 13 int cnt = 0 ; 14 int path[N],dis[N][N]; 15 int vis[N] ; 16 int flag = 0 ; 17 18 void Add_Edge( string u , string v ){ 19 int No_U = Name2num[u]; 20 int No_V = Name2num[v]; 21 22 G[No_U].push_back( No_V ) ; 23 G[No_V].push_back( No_U ) ; 24 dis[No_V][No_U] = dis[No_U][No_V] = 1 ; 25 } 26 27 void print_Path(){ 28 for( int i = 0 ; i < cnt ; i ++ ){ 29 cout << Num2name[path[i]] << " " ; 30 } 31 //cout << " ######## "<< endl; 32 cout << endl ; 33 } 34 35 void dfs( int No , int S , int End ){ 36 if( No == End ){ 37 flag = 1 ; 38 print_Path(); 39 return ; 40 } 41 if( flag ) return ; 42 43 //利用dis[S][To] + dis[To][End] == dis[S][End](最短路径)的特点 44 for(int i = 0 ; i < (int)G[No].size() ; i++ ){ 45 int To = G[No][i]; 46 if( vis[To] == 0 && dis[S][To] + dis[To][End] == dis[S][End]){ 47 vis[ No ] = 1 ; 48 path[cnt] = To ; 49 cnt ++ ; 50 dfs( To , S , End ); 51 cnt -- ; 52 vis[ No ] = 0 ; 53 } 54 } 55 56 } 57 58 int main() 59 { 60 //初始化:输入+建图 61 int n = 0 , m = 0 ; 62 cin >> m ; 63 memset( dis , 0x3f , sizeof dis ); 64 G.push_back( vector<int>() ); 65 for( int i = 0 ; i < m ; i++ ){ 66 string u , v ; 67 cin >> u >> v ; 68 if( Name2num[u] == 0 ) { 69 G.push_back( vector<int>() ); 70 Name2num[u] = ++ n , Num2name[n] = u ; 71 } 72 if( Name2num[v] == 0 ) { 73 G.push_back( vector<int>() ); 74 Name2num[v] = ++ n , Num2name[n] = v ; 75 } 76 Add_Edge( u , v ); 77 } 78 79 //利用Flody来计算图中任意两点间距离 80 for( int k = 1 ; k <= n ; k ++ ){ 81 dis[k][k] = 0 ; 82 for( int i = 1 ; i <= n ; i++ ){ 83 for( int j = 1 ; j <= n ; j ++ ){ 84 if( dis[i][j] > dis[i][k] + dis[k][j] ){ 85 dis[i][j] = dis[i][k] + dis[k][j] ; 86 } 87 } 88 } 89 } 90 91 //用DFS再次搜索一遍. 92 string S , E ; 93 cin >> S >> E ; 94 if( dis[ Name2num[S] ][ Name2num[E] ] == 0x3f3f3f3f ){ 95 printf("不存在路径 "); 96 }else{ 97 path[cnt++] = Name2num[S]; 98 99 dfs( Name2num[S] , Name2num[S] , Name2num[E] ) ; 100 } 101 return 0; 102 } 103 /* 104 6 105 M L 106 M J 107 J A 108 A S 109 L A 110 L S 111 112 M S 113 114 output: 115 M L S 116 */