题目来源:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=589
Professor John
Time Limit: 2 Seconds Memory Limit: 65536 KB
Sunny Cup 2003 - Preliminary Round
April 20th, 12:00 - 17:00
Problem H: Professor John
Professor John is investigating a math problem. He has obtained some relationsamong several variables. Now he would like to know if there are any otherrelations that can be deduced from these obtained ones. Since he has beenworking for too long, Professor John decides to grant himself a vacation whileassigning you to do the job. Are you ready?
Input
The first line of input contains an integerN, which is the number of test cases. Then N test cases follow.
For each test case:
the 1st line contains a positive integer m (<= 100) which is the number ofgiven relations;
the following m lines each contains a given relation, in the format
Variable1<Variable2
or
Variable1>Variable2
A "Variable" is represented by acapital character. There will not be conflicting relations given.
Output
For each test case, first print in one line"Case d:" where d is the number of the test case, start counting from1.
Then output all the relations which can be deduced from the given relations inalphabetical order, in the format Variable1<Variable2. Each relationoccupies one line. No extra space shall be printed. The given relations mustNOT be included.
If no new relation is found, output "NONE" in one line.
Sample Input
2
3
A<B
C>B
C<D
2
A<B
C<D
Sample Output
Case 1:
A<C
A<D
B<D
Case 2:
NONE
-----------------------------------------------------
思路
实际上是求传递闭包问题,用Floyd算法求解。
(1) 建图:如果A<B,则A->B之间连一条有向边
(2) 求连通节点:如果节点A1,A2之间有从A1指向A2的长度大于1的有向道路,则可以推出”A1<A2”。用Floyd算法求解
关于Floyd算法的详细介绍参见博文最短路径问题---Floyd算法详解
核心算法(三层循环):
for (i=0; i<=mymax; i++) { for (j=0; j<=mymax; j++) { for (k=0; k<=mymax; k++) { if (nat[j][i] && nat[i][k]) { nat[j][k] = 1; } } } }此题的坑点在于输出要按字典顺序,为此WA了11次。
-----------------------------------------------------
代码
#include<iostream> #include<fstream> #include<cstring> #include<string> #include<stdio.h> using namespace std; const int NMAX = 105; bool mat[NMAX][NMAX] = {}; bool nat[NMAX][NMAX] = {}; int main() { #ifndef ONLINE_JUDGE ifstream fin ("0308_3529.txt"); int t,n,ii,i,j,k,a,b,cnt=1,mymax = 0; bool has = false; string s; fin >> t; for (ii=0; ii<t; ii++) { memset(mat, 0, sizeof(mat)); memset(nat, 0, sizeof(nat)); has = false; mymax = 0; fin >> n; cout << "Case " << (cnt++) << ":" << endl; for (i=0; i<n; i++) { fin >> s; a = s.at(0)-'A'; b = s.at(2)-'A'; mymax = max(mymax,a); mymax = max(mymax,b); if (s.at(1)=='<') { mat[a][b] = 1; nat[a][b] = 1; } else { mat[b][a] = 1; nat[b][a] = 1; } } for (i=0; i<=mymax; i++) { for (j=0; j<=mymax; j++) { for (k=0; k<=mymax; k++) { if (nat[j][i] && nat[i][k]) { nat[j][k] = 1; } } } } for (j=0; j<=mymax; j++) { for (k=0; k<=mymax; k++) { if (nat[j][k] && !mat[j][k]) { cout << (char)(j+'A') << "<" << (char)(k+'A') << endl; has = true; } } } if (!has) { cout << "NONE" << endl; } } fin.close(); #endif #ifdef ONLINE_JUDGE int t,n,ii,i,j,k,a,b,cnt=1,mymax = 0; bool has = false; char s[4] = {}; scanf("%d",&t); for (ii=0; ii<t; ii++) { memset(mat, 0, sizeof(mat)); memset(nat, 0, sizeof(nat)); has = false; mymax = 0; scanf("%d",&n); cout << "Case " << (cnt++) << ":" << endl; for (i=0; i<n; i++) { scanf("%s",s); a = s[0]-'A'; b = s[2]-'A'; mymax = max(mymax,a); mymax = max(mymax,b); if (s[1]=='<') { mat[a][b] = 1; nat[a][b] = 1; } else { mat[b][a] = 1; nat[b][a] = 1; } } for (i=0; i<=mymax; i++) { for (j=0; j<=mymax; j++) { for (k=0; k<=mymax; k++) { if (nat[j][i] && nat[i][k]) { nat[j][k] = 1; } } } } for (j=0; j<=mymax; j++) { for (k=0; k<=mymax; k++) { if (nat[j][k] && !mat[j][k]) { cout << (char)(j+'A') << "<" << (char)(k+'A') << endl; has = true; } } } if (!has) { cout << "NONE" << endl; } } #endif }