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 由 温婕莺