题目链接: http://acm.zzuli.edu.cn/problem.php?id=1676
题目描述
新学年开学了,学校又迎来了一批新同学,已知部分同学之间的身高关系,请列出可推断出的同学之间的身高关系。
输入
第一行是一个整数n,表示有n组测试数据。
每组测试数据第一行是一个正整数m(m<=100),表示已知同学之间的身高关系有m组,身高关系没有相等的情况。
接下来输入m行身高关系,每位同学用一个大写字母表示。
输出
对于第d组测试数据,首先输出“Case d:”,d从1开始。
输出能够推断出的同学之间的身高关系,按字母的字典序输出。
已知条件中的身高关系不要输出。
如果推断不出任何新的身高关系,输出NONE。
样例输入
2
3
A<B
C>B
C<D
2
A<B
C<D
样例输出
Case 1:
A<C
A<D
B<D
Case 2:
NONE
解法1:DFS
1 #include <bits/stdc++.h> 2 using namespace std; 3 bool vis[30][30]; 4 int m; 5 vector<int>V[30]; 6 struct node 7 { 8 int a, b; 9 } q[1004]; 10 bool cmp(node x, node y) 11 { 12 if(x.a == y.a) return x.b < y.b; 13 return x.a < y.a; 14 } 15 void dfs(int x, int y) 16 { 17 for(int i = 0; i < V[y].size(); i++) 18 { 19 int v = V[y][i]; 20 if(!vis[x][v]) 21 { 22 q[++m].a = x; 23 q[m].b = v; 24 } 25 dfs(x, v); 26 } 27 } 28 int main() 29 { 30 int t, n, i; 31 cin>>t; 32 int cas = 0; 33 while(t--) 34 { 35 scanf("%d", &n); 36 for(i = 0; i < 26; i++) V[i].clear(); 37 memset(vis, 0, sizeof vis); 38 m = 0; 39 while(n--) 40 { 41 char s[5]; 42 scanf("%s", s); 43 int a = s[0] - 'A'; 44 int b = s[2] - 'A'; 45 if(s[1] == '<') V[a].push_back(b), vis[a][b] = 1; 46 else V[b].push_back(a), vis[b][a] = 1; 47 } 48 printf("Case %d: ", ++cas); 49 for(i = 0; i < 26; i++) 50 dfs(i, i); 51 sort(q+1, q+1+m, cmp); 52 for(i = 1; i <= m; i++) 53 printf("%c<%c ", q[i].a+'A', q[i].b+'A'); 54 if(!m) puts("NONE"); 55 } 56 return 0; 57 }
解法2:BFS
1 #include <bits/stdc++.h> 2 using namespace std; 3 bool vis[30][30]; 4 int m; 5 vector<int>V[30]; 6 struct node 7 { 8 int a, b; 9 } q[1004]; 10 bool cmp(node x, node y) 11 { 12 if(x.a == y.a) return x.b < y.b; 13 return x.a < y.a; 14 } 15 int main() 16 { 17 int t, n, i; 18 cin>>t; 19 int cas = 0; 20 while(t--) 21 { 22 scanf("%d", &n); 23 for(i = 0; i < 26; i++) V[i].clear(); 24 memset(vis, 0, sizeof vis); 25 m = 0; 26 while(n--) 27 { 28 char s[5]; 29 scanf("%s", s); 30 int a = s[0] - 'A'; 31 int b = s[2] - 'A'; 32 if(s[1] == '<') V[a].push_back(b), vis[a][b] = 1; 33 else V[b].push_back(a), vis[b][a] = 1; 34 } 35 printf("Case %d: ", ++cas); 36 for(i = 0; i < 26; i++) 37 { 38 queue<int>Q; 39 Q.push(i); 40 while(!Q.empty()) 41 { 42 int t = Q.front(); 43 Q.pop(); 44 for(int j = 0; j < V[t].size(); j++) 45 { 46 int v = V[t][j]; 47 if(!vis[i][v]) 48 { 49 q[++m].a = i; 50 q[m].b = v; 51 } 52 Q.push(v); 53 } 54 } 55 } 56 sort(q+1, q+1+m, cmp); 57 for(i = 1; i <= m; i++) 58 printf("%c<%c ", q[i].a+'A', q[i].b+'A'); 59 if(!m) puts("NONE"); 60 } 61 return 0; 62 }
解法3:并查集
1 #include <bits/stdc++.h> 2 using namespace std; 3 int vis[30][30], par[30]; 4 int main() 5 { 6 int n, m, i, j; 7 char s[5]; 8 cin>>n; 9 int cas = 0; 10 while(n--) 11 { 12 scanf("%d", &m); 13 for(i = 0; i < 26; i++) par[i] = i; 14 memset(vis, 0, sizeof vis); 15 while(m--) 16 { 17 scanf("%s", s); 18 int a = s[0] - 'A'; 19 int b = s[2] - 'A'; 20 if(s[1] == '<') 21 par[a] = b, vis[a][b] = 1; 22 else 23 par[b] = a, vis[b][a] = 1; 24 } 25 printf("Case %d: ", ++cas); 26 m = 0; 27 for(i = 0; i < 26; i++) 28 { 29 for(j = 0; j < 26; j++) 30 { 31 int k = i; 32 if(i == j) continue; 33 while(1) 34 { 35 k = par[k]; 36 if(k == j && !vis[i][j]) 37 { 38 printf("%c<%c ", i+'A', j+'A'); 39 m++; 40 } 41 if(k == par[k]) break; 42 } 43 } 44 } 45 if(!m) puts("NONE"); 46 } 47 return 0; 48 }
解法4:floyd
1 #include <bits/stdc++.h> 2 using namespace std; 3 int mp[30][30]; 4 int main() 5 { 6 int t, n; 7 cin>>t; 8 int cas = 0; 9 while(t--) 10 { 11 scanf("%d", &n); 12 memset(mp, 0, sizeof mp); 13 bool f = false; 14 while(n--) 15 { 16 char s[5]; 17 scanf("%s", s); 18 int a = s[0] - 'A'; 19 int b = s[2] - 'A'; 20 if(s[1] == '<') mp[a][b] = 1; 21 else mp[b][a] = 1; 22 } 23 printf("Case %d: ", ++cas); 24 for(int k = 0; k < 26; k++) 25 for(int i = 0; i < 26; i++) 26 for(int j = 0; j < 26; j++) 27 if(mp[i][k] && mp[k][j] && !mp[i][j]) 28 mp[i][j] = 2, f = true; 29 for(int i = 0; i < 26; i++) 30 for(int j = 0; j < 26; j++) 31 if(mp[i][j] == 2) 32 printf("%c<%c ", i+'A', j+'A'); 33 if(!f) puts("NONE"); 34 } 35 return 0; 36 }