璟雯院

珺璟如晔,雯华若锦

用户工具

站点工具


icpc:problems:usaco22feb_redistributing_gifts_s
problems
名称Redistributing Gifts S
题目编号USACO22FEB_S1
题目链接luogu.com.cn/…
来源USACO
算法分类图论, 传递闭包
难易程度容易

Redistributing Gifts S

想法

每次要求可能换到的最优礼物,意味着:x想要得到y,并且y想要将礼物给出去换得更好的礼物,而在交换的路上可以将礼物y交给x。

求的是最优礼物而不是一次优秀的交换情况,所以不需要担心交换后续的情况,只需要知道能否交换即可。

设F[x][y],表示x想要y,也就是x存在一条指向y的边。通过Floyd的方式 如果F[x][k] && F[k][y] ⇒ F[x][y] = true.

代码实现

#include<iostream>
#include<vector>
using namespace std;
 
const int N = 510;
 
int maps[N][N];
int tong[N];
bool F[N][N];
 
int main()
{
	int n;
	cin >> n;
	for (int i = 1; i <= n; ++i) 
		tong[i] = i;
	for (int i = 1; i <= n; ++i) 
		for (int j = 1; j <= n; ++j) 
			cin >> maps[i][j];
 
	for (int i = 1; i <= n; ++i) 
		for (int j = 1; j <= n; ++j) {
			F[i][maps[i][j]] = true;
			if(maps[i][j] == i)break;
		}
 
	for (int k = 1; k <= n; ++k) 
		for (int i = 1; i <= n; ++i) 
			for (int j = 1; j <= n; ++j) 
				if(F[i][k] && F[k][j])
					F[i][j] = true;
 
	for (int i = 1; i <= n; ++i) 
		for (int j = 1; j <= n; ++j)
			if(F[maps[i][j]][i])
			{
				tong[i] = maps[i][j];
				break;
			}
 
	for (int i = 1; i <= n; ++i) 
		cout << tong[i] << '\n';
 
	return 0;
}
/app/www/public/data/pages/icpc/problems/usaco22feb_redistributing_gifts_s.txt · 最后更改: 2023/04/15 12:39 由 温婕莺