【搜索+最短路】找朋友

时间:2020-03-26
本文章向大家介绍【搜索+最短路】找朋友,主要包括【搜索+最短路】找朋友使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

【题目】

  找朋友

【题意】

  找朋友:已知一组人名对,他们互为朋友关系,输入一个人名对,找到两个人认识的最短关系路径

例如:<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搜索,最后打印路径

  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("不存在路径\n");
 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  */
View Code

原文地址:https://www.cnblogs.com/Osea/p/12572938.html