大致题意就是A看上了B,A要通过同性别朋友C,如果C认识D,且D是B的同性别朋友,那么A就可以追求B了。
方法一:DFS暴力枚举法,凉凉~~。
1 #include<iostream> 2 #include<vector> 3 #include<unordered_map> 4 #include<algorithm> 5 using namespace std; 6 7 struct node { 8 int a,b; 9 }; 10 const int maxn = 310; 11 int n,m,k; 12 13 vector<int> G[maxn],path; 14 bool visited[maxn] = {false}; 15 vector<node> ans; 16 bool cmp(node& a,node& b) { 17 if(a.a != b.a) return a.a < b.a; 18 else return a.b < b.b; 19 } 20 unordered_map<string,int> IDtoInt; 21 unordered_map<int,string> IntToID; 22 int num = 1; 23 int getID(string id) { 24 if(IDtoInt.count(id) == 0) { 25 IDtoInt[id] = num; 26 IntToID[num++] = id; 27 } 28 return IDtoInt[id]; 29 } 30 31 void DFS(int now,int end,int len) { 32 if(len == 4) { 33 if(now == end) { 34 path.push_back(end); 35 if(IntToID[path[0]].size() == IntToID[path[1]].size() &&IntToID[path[2]].size() == IntToID[path[3]].size() ) 36 ans.push_back({abs(stoi(IntToID[path[1]])),abs(stoi(IntToID[path[2]]))}); 37 path.pop_back(); 38 } 39 return ; 40 } 41 if(now == end && len < 4) return; 42 visited[now] = true; 43 path.push_back(now); 44 for(int i = 0; i < G[now].size(); ++i) { 45 if(visited[G[now][i]] == false) 46 DFS(G[now][i],end,len+1); 47 } 48 visited[now] = false; 49 path.pop_back(); 50 } 51 int main() { 52 scanf("%d%d",&n,&m); 53 string a,b; //必须考虑 -0000,0000的情况,所以用string 54 for(int i = 0; i < m; ++i) { 55 cin>>a>>b; 56 int u = getID(a),v = getID(b); 57 G[u].push_back(v); 58 G[v].push_back(u); 59 } 60 scanf("%d",&k); 61 while(k--) { 62 cin>>a>>b; 63 ans.clear(); 64 DFS(IDtoInt[a],IDtoInt[b],1); 65 sort(ans.begin(),ans.end(),cmp); 66 printf("%d\n",ans.size()); 67 for(int i = 0; i < ans.size(); ++i) printf("%04d %04d\n",ans[i].a,ans[i].b); 68 } 69 return 0; 70 }
方法二:
用map建立 ID与编号的对应关系。
用邻接表,保存一对顶点的朋友关系。
用邻接矩阵,保存某个人的所有同性别朋友。
如果A的同性朋友是C,B的同性朋友是D,若C与D是朋友关系,那么A可以追求B。
注意点:
1,编号必须从1开始,因为给出的ID可能非法,其对应编号为0表示未找到这个人,不然测试点 5无法通过。
2,注意输入为 -0000的情况,必须用string接受 -0000
1 #include<iostream> 2 #include<vector> 3 #include<algorithm> 4 #include<unordered_map> 5 using namespace std; 6 const int maxn = 320; 7 struct node { 8 int a,b; 9 }; 10 int n,m,k,G[maxn][maxn]; 11 vector<int> adj[maxn]; 12 bool cmp(node a,node b) { 13 if(a.a != b.a) return a.a < b.a; 14 else return a.b < b.b; 15 } 16 unordered_map<string,int> IDtoInt; 17 unordered_map<int,string> IntToID; 18 int num = 1; //写成 num = 0时,导致测试点5无法通过,因为输入非法ID时IDtoInt[ID] = 0,所以合法编号num从1开始 19 int getID(string id) { 20 if(!IDtoInt.count(id)) { 21 IDtoInt[id] = num; 22 IntToID[num++] = id; 23 } 24 return IDtoInt[id]; 25 } 26 int main() { 27 fill(G[0],G[0]+maxn*maxn,0); 28 cin>>n>>m; 29 string a,b; 30 for(int i = 0; i < m; ++i) { 31 cin>>a>>b;//这样读取的原因是有易错点:-0000 32 int u = getID(a),v = getID(b); 33 G[u][v] = G[v][u] = 1;//朋友关系 34 if(a.size() == b.size()) { //同性朋友关系 35 adj[u].push_back(v); 36 adj[v].push_back(u); 37 } 38 } 39 cin>>k; 40 while(k--) { 41 cin>>a>>b; 42 vector<node> ans; 43 int u = IDtoInt[a],v = IDtoInt[b]; 44 for(int i = 0; i < adj[u].size(); ++i) { //找u的同性朋友 C 45 int c = adj[u][i]; 46 for(int j = 0; j < adj[v].size(); ++j) {//找v的同性朋友 D 47 int d = adj[v][j]; 48 if(v == c || u == d) continue; 49 if(G[c][d]) ans.push_back({abs(stoi(IntToID[c])),abs(stoi(IntToID[d]))}); 50 } 51 } 52 sort(ans.begin(),ans.end(),cmp); 53 printf("%d\n",ans.size()); 54 for(int i = 0; i < ans.size(); ++i) 55 printf("%04d %04d\n",ans[i].a,ans[i].b); 56 } 57 return 0; 58 }
方法三:
开很大的数组,直接映射ID,无需使用map。
1 #include<iostream> 2 #include<vector> 3 #include<algorithm> 4 5 using namespace std; 6 const int maxn = 10000; 7 struct node { 8 int a,b; 9 }; 10 int n,m,k,G[maxn][maxn]= {0}; 11 vector<int> adj[maxn]; 12 bool cmp(node a,node b) { 13 if(a.a != b.a) return a.a < b.a; 14 else return a.b < b.b; 15 } 16 int main() { 17 cin>>n>>m; 18 string a,b; 19 for(int i = 0; i < m; i++) { 20 cin>>a>>b;//这样读取的原因是有易错点:-0000 21 int u = abs(stoi(a)),v = abs(stoi(b)); 22 G[u][v] = G[v][u] = 1; 23 if(a.size() == b.size()) {//同性朋友 24 adj[u].push_back(v); 25 adj[v].push_back(u); 26 } 27 } 28 cin>>k; 29 while(k--) { 30 cin>>a>>b; 31 vector<node> ans; 32 int u = abs(stoi(a)),v = abs(stoi(b)); 33 for(int i = 0; i < adj[u].size(); i++) { 34 int c = adj[u][i]; 35 for(int j = 0; j < adj[v].size(); j++) { 36 int d = adj[v][j]; 37 if(v == c || u == d) continue; 38 if(G[c][d]) ans.push_back({c,d}); 39 } 40 } 41 sort(ans.begin(),ans.end(),cmp); 42 printf("%d\n",ans.size()); 43 for(int i = 0; i < ans.size(); i++) { 44 printf("%04d %04d\n",ans[i].a,ans[i].b);//%04d为易错点 45 } 46 } 47 return 0; 48 }