NOI 3.8 图 3529: Professor John(传递闭包,Floyd算法)

题目来源: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

扫描二维码关注公众号,回复: 1630340 查看本文章

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
}


猜你喜欢

转载自blog.csdn.net/da_kao_la/article/details/80723562
3.8