【zzulioj-1676】与同学比身高(综合)
题目链接: 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:\n", ++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\n", 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:\n", ++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\n", 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:\n", ++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\n", 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:\n", ++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\n", i+'A', j+'A');
33 if(!f) puts("NONE");
34 }
35 return 0;
36 }