結果
問題 | No.2301 Namorientation |
ユーザー |
![]() |
提出日時 | 2023-05-12 22:29:24 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 650 ms / 3,000 ms |
コード長 | 4,434 bytes |
コンパイル時間 | 1,644 ms |
コンパイル使用メモリ | 127,440 KB |
最終ジャッジ日時 | 2025-02-12 23:13:34 |
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 30 |
ソースコード
//#pragma GCC target("avx2")//#pragma GCC optimize("O3")//#pragma GCC optimize("unroll-loops")#include <iostream>#include <iomanip>#include <algorithm>#include <vector>#include <string>#include <set>#include <map>#include <cassert>#include <cmath>#include <tuple>#include <queue>#include <bitset>using namespace std;using lg = unsigned long long;#define TEST clog << "TEST" << endl#define IINF 2147483647#define LLINF 9223372036854775807LL//#define AMARI 1000000007#define AMARI 998244353#define TEMOTO ((sizeof(long double) == 16) ? false : true)#define TIME_LIMIT 1980 * (TEMOTO ? 1 : 1000)#define el '\n'#define El '\n'class ococo_unionfind {//できること//点の挿入//その点の根を求める関数//辺の挿入//連結判定//島が何個あるかの出力//それぞれの島について、何個の点があるかの出力public:ococo_unionfind(int n = 0) {for (int i = 0; i < n; i++)vinsert();}int simakosuu = 0;//g[i] = {その点の一個上の点,その点のrank}//その点のrank:その点の下に何個点があるか(上に何個あるかに変えた方がいいかも?)vector<pair<int, int>> g;//rs[i] = その点が含まれている連結成分に何個の点があるか//その連結成分の根について聞かないと返さないvector<int> rs;//点の挿入 O(1)void vinsert(void) {g.emplace_back(g.size(), 1);simakosuu++;rs.push_back(1);}//ある点の根を求める関数 O(α(N))int ne(int a) {if (g[a].first == a)return a;else {return g[a].first = ne(g[a].first);}}//辺の挿入 O(logN)void einsert(int a, int b) {if (a != b) {int a1 = ne(a), a2 = ne(b);if (a1 != a2) {simakosuu--;int rs12sum = rs[a1] + rs[a2];rs[a1] = rs12sum;rs[a2] = rs12sum;if (g[a1].second < g[a2].second) {g[a1].first = a2;g[a2].second = max(g[a1].second + 1, g[a2].second);}else {g[a2].first = a1;g[a1].second = max(g[a2].second + 1, g[a1].second);}}}}//2つのノードが繋がっているか判定する関数 O(α(N))bool renketucheck(int a, int b) {if (ne(a) == ne(b))return true;else return false;}//何個の島に分かれているか出力する関数 O(1)int islandnum(void) {return simakosuu;}//ある点について、その点が含まれている連結成分が何個の点を持つか返す関数 O(α(N))int islandsize(int a) {return rs[ne(a)];}};vector<vector<int>> g;map<pair<int, int>, int> mp;vector<bool> ans;void dfs(int p, int t) {for (int i = 0; i < g[t].size(); i++) {if (g[t][i] != p)dfs(t, g[t][i]);}if (mp.find({ p,t }) != mp.end())ans[mp[{p, t}]] = true;if (mp.find({ t,p }) != mp.end())ans[mp[{t, p}]] = false;}#define MULTI_TEST_CASE falsevoid solve(void) {int n;cin >> n;g.resize(n); ans.resize(n);ococo_unionfind ouf(n);int oya = -1,oyaaikata = -1;for (int i = 0; i < n; i++) {int u, v;cin >> u >> v;u--; v--;mp[{u, v}] = i;if (!ouf.renketucheck(u, v)) {ouf.einsert(u, v);g[u].push_back(v);g[v].push_back(u);}else {oya = u;oyaaikata = v;}}//ans[{x,y}] == true の時、yからxに出ているdfs(-1, oya);if (mp.find({ oya,oyaaikata }) != mp.end())ans[mp[{oya, oyaaikata}]] = false;else ans[mp[{oyaaikata, oya}]] = true;for (int i = 0; i < n; i++) {if (ans[i])cout << "<-\n";else cout << "->\n";}return;}void calc(void) {vector<int> v = { 0,0,0,1,1 };do {for (int i = 0; i < 5; i++) {cout << v[i];}cout << el;} while (next_permutation(v.begin(), v.end()));return;}int main(void) {cin.tie(nullptr);ios::sync_with_stdio(false);int t = 1;if (MULTI_TEST_CASE)cin >> t;while (t--) {solve();}//calc();return 0;}