UVA - 247Calling Circles

题目传送门

​
/*
	来自算法竞赛入门经典刘汝佳p364
	把Floyd中的"d[i][j] = min(d[i][j], d[i][k] + d[k][j])"改成
	"d[i][j] = d[i][j]||(d[i][k]&&d[k][j])"通过这样来求有向图的传递闭包
*/
#include<iostream>
#include <stdio.h>
#include <string>
#include <string.h>
#include <vector>
#define MAXN 36
using namespace std;
vector<string> name;
int n;
int mmp[MAXN][MAXN];
bool book[MAXN];
int getid(string x)
{//新学到的一招,把string变成代号的方法
	for (int i = 0; i < name.size(); i++)
		if (name[i] == x)return i;
	name.push_back(x);
	return name.size() - 1;
}
void dfs(int id)
{//对传递闭包遍历
	book[id] = true;
	for (int i = 0; i < n; i++)
		if (!book[i] && mmp[id][i] && mmp[i][id])
		{//如果满足它没有被访问过并且它在闭包里打印它
			//在闭包里的意思就是mmp[i][j] == mmp[j][i]
			cout << ", " << name[i];
			dfs(i);
		}
}
int main(void)
{
	int m, k = 0;

	while (scanf_s("%d%d", &n, &m) != EOF&&n+m)
	{
		if (k > 0)putchar('\n');
		printf("Calling circles for data set %d:\n", ++k);
		memset(mmp, 0, sizeof(mmp));
		memset(book, 0, sizeof(book));
		name.clear();//数据初始化

		for (int i = 0; i < m; i++)
		{
			string name1, name2;

			cin >> name1 >> name2;
			mmp[getid(name1)][getid(name2)] = 1;
		}
		for (int k = 0; k < n; k++)
			for (int i = 0; i < n; i++)
				for (int j = 0; j < n; j++)//Flody求传递闭包
					mmp[i][j] = mmp[i][j] || (mmp[i][k] && mmp[k][j]);
		for (int i = 0; i < n; i++)
		{//对每一个数进行遍历
			if (!book[i])
			{//倘若它没有被打印过那就进入深搜
				cout << name[i];
				dfs(i);
				putchar('\n');
			}
		}
	}

	return 0;
}

​

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值