• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
jacklee404
Never Stop!
博客园    首页    新随笔    联系   管理    订阅  订阅
排序 Floyd-计算传递闭包

排序 Floyd-计算传递闭包

题目

排序

思路

​ 考虑\(d[i][j]\)只有两种边权\(0/1\), \(0\)表示\(i\)和\(j\)的关系未知, \(1\)表示\(i < j\) (即\(d[i][j]\)表示两点之间是否连同的问题)

​ 第一种情况是已经排序好,第二种是存在环的情况 (例如\(i < j\) ,\(j < i\)), 在排除第二种的情况下我们只需要判断每个点到其他点的距离是否已经已知,即对任意的\((i, j) 满足 d[i][j] 或 d[j][i]\)

​ 由于数据量很小我们可以考虑Floyd, 复杂度\(O(N^3 \times m)\)

​ 由于每次只更新一条边,我们可以考虑优化上述算法:

image-20230504202857329

​ 考虑新加入的点是\(u\rightarrow v\), 由于我们考虑更新过程中无环才继续更新的,所以我们更新只考虑\(d[x][u]\)和\(d[v][y]\)为\(1\)的点进行更新,另外更新过程中将\(d[x][u]为1的点更新d[x][v]为1\),将\(d[v][y]为1的点更新d[u][y]为1\) , 复杂度为\(O(N^2 \times m)\)

Code

#include <bits/stdc++.h>

using i64 = long long;

const int N = 30;

int n, m;

bool d[N][N];

void one_floyd(int u, int v) {	
	// for (int k = 0; k < n; k ++) {
	// 	for (int i = 0; i < n; i ++) {
	// 		for (int j = 0; j < n; j ++) {
	// 			d[i][j] |= d[i][k] && d[k][j];
	// 		}
	// 	}
	// }

	for (int i = 0; i < n; i ++) {
		if (d[i][u]) d[i][v] = 1; 
		if (d[v][i]) d[u][i] = 1;
		for (int j = 0; j < n; j ++) {
			if (d[i][u] && d[v][j]) {
				d[i][j] = 1;
			}
		}
	}
}

int check() {
	for (int i = 0; i < n; i ++) {
		// std::cout << d[i][i] << " \n"[i == n - 1];
		if (d[i][i])
			return 2;
	}


	for (int i = 0; i < n; i ++)
		for (int j = 0; j < i; j ++)
			if (!d[i][j] && !d[j][i])
				return 0;

	return 1;
}

int main() {
	while (std::cin >> n >> m, n || m) {
		memset(d, 0, sizeof d);
		
		int type = 0, cnt = 0;

		for (int i = 1; i <= m; i ++) {
			std::string t;
			
			std::cin >> t;

			int a = t[0] - 'A', b = t[2] - 'A';

			if (!type) {
				d[a][b] = 1;
			
				one_floyd(a, b);
			
				type = check();

				// std::cout << type << "\n";
				
				if (type) cnt = i;	
			}	
		}

		std::string ans;

		for (int i = 0; i < n; i ++) ans.push_back(i + 'A');

		if (!type) puts("Sorted sequence cannot be determined.");
		else if (type == 2) printf("Inconsistency found after %d relations.\n", cnt);
		else {
			std::sort(ans.begin(), ans.end(), [](char a, char b) {
				return d[a - 'A'][b - 'A'];
			});
			printf("Sorted sequence determined after %d relations: %s.\n", cnt, ans.c_str());
		}
	}
}
posted on 2023-05-04 20:44  Jack404  阅读(43)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3