值得借鉴的代码
数据结构板子
#include <iostream> #include <iomanip> #include <cstdio> #include <cstdint> #include <cstddef> #include <cmath> #include <cstring> #include <cassert> #include <ctime> #include <algorithm> #include <chrono> #include <functional> #include <numeric> #include <utility> #include <array> #include <map> #include <queue> #include <set> #include <stack> #include <vector> using namespace std; #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> #include <ext/rope> using namespace __gnu_pbds; using namespace __gnu_cxx; namespace dutinmeow { namespace types { using int8 = int_fast8_t; using int16 = int_fast16_t; using int32 = int_fast32_t; using int64 = int_fast64_t; using ll = int_fast64_t; #define int int32 using uint8 = uint_fast8_t; using uint16 = uint_fast16_t; using uint32 = uint_fast32_t; using uint64 = uint_fast64_t; using ull = uint_fast64_t; using pii = pair<int, int>; using piii = pair<int, pii>; using pll = pair<ll, ll>; using plll = pair<ll, pll>; template<class K, class V> using ordered_map = tree<K, V, less<K>, rb_tree_tag, tree_order_statistics_node_update>; template<class K> using ordered_set = ordered_map<K, null_type>; } using namespace types; namespace constants { const int inf = 2000000011; const ll llinf = 999999999999999989; const int MOD = 1e9 + 7; const double PI = acos(-1); const int di[] = {-1, 0, 1, 0}; const int dj[] = {0, 1, 0, -1}; } using namespace constants; namespace macros { #define PB push_back #define PF push_front #define PPB pop_back #define PPF pop_front #define EB emplace_back #define EF emplace_front #define MP make_pair #define FF first #define SS second } using namespace macros; namespace hash { struct chash { const uint64_t C = ll(2e18 * PI) + 71; const int RANDOM = chrono::high_resolution_clock::now().time_since_epoch().count(); inline ll operator()(ll x) const { return __builtin_bswap64((x ^ RANDOM) * C); } inline ll operator()(pll p) const { return (*this)(p.FF) ^ (*this)(p.SS); } }; template<class K, class V> using fast_map = gp_hash_table<K, V, chash>; template<class K> using fast_set = fast_map<K, null_type>; } using namespace hash; namespace functions { inline void stop() { assert(0); } template<typename T> inline void sort(T& c) { sort(c.begin(), c.end()); } template<typename T, typename S> inline void sort(T& c, S s) { sort(c.begin(), c.end(), s); } template<typename T> inline void reverse(T& c) { reverse(c.begin(), c.end()); } // lambda template: [](const C& a, const C& b) { return a > b; } inline ll ceil0(ll a, ll b) { return a / b + ((a ^ b) > 0 && a % b); } inline ll floor0(ll a, ll b) { return a / b - ((a ^ b) < 0 && a % b); } ll pow0(ll a, ll b) { ll res = 1; for (a %= MOD; b; b >>= 1) { if(b & 1) res = res * a % MOD; a = a * a % MOD; } return res; } template<typename T> string binary(T b) { string res = ""; for (int i = sizeof(T) * 8 - 1; i >= 0; i--) res += (b & (1 << i) ? '1' : '0'); return res; } template<typename T> string binary(T b, int k) { string res = ""; for (int i = k; i >= 0; i--) res += ((b & (1 << i)) ? '1' : '0'); return res; } } using namespace functions; namespace input { void filein(const string FILENAME) { freopen(FILENAME.c_str(), "r", stdin); } inline void read() {} template<typename T, typename... U> inline void read(T& F, U&... S) { cin >> F; read(S...); } // pair template<typename T1, typename T2> inline istream& operator>>(istream& is, pair<T1, T2>& p) { return is >> p.FF >> p.SS; } // std::array<T, N> template<typename T, size_t sz> inline istream& operator>>(istream& is, array<T, sz>& a) { for (auto& x : a) is >> x; return is; } template<typename T, size_t sz> void read(array<T, sz>& a, int n) { assert(0 <= n && n < a.size()); for (int i = 0; i < n; i++) cin >> a[i]; } template<typename T, size_t sz> void read(array<T, sz>& a, int l, int r) { assert(0 <= l && l <= r && r < a.size()); for (int i = l; i <= r; i++) cin >> a[i]; } // std::vector<T> template<typename T> inline istream& operator>>(istream& is, vector<T>& v) { for (auto& x : v) is >> x; return is; } template<typename T> void read(vector<T>& v, int n) { assert(0 <= n && n < v.size()); for (int i = 0; i < n; i++) cin >> v[i]; } template<typename T> void read(vector<T>& v, int l, int r) { assert(0 <= l && l <= r && r < v.size()); for (int i = l; i <= r; i++) cin >> v[i]; } } using namespace input; namespace output { void fileout(const string FILENAME) { freopen(FILENAME.c_str(), "w", stdout); } void fileerr(const string FILENAME) { freopen(FILENAME.c_str(), "w", stderr); } template<typename T1, typename T2> ostream& operator<<(ostream& os, const pair<T1, T2>& p) { return os << '(' << p.FF << ", " << p.SS << ')'; } template<typename T> ostream& operator<<(ostream& os, const vector<T>& v) { os << '['; if (v.size()) { os << *v.begin(); for (auto i = ++v.begin(); i != v.end(); i++) os << ", " << (*i); } return os << ']'; } template<typename T> ostream& operator<<(ostream& os, const ordered_set<T>& s) { os << '['; if (s.size()) { os << *s.begin(); for (auto i = ++s.begin(); i != s.end(); i++) os << ", " << (*i); } return os << ']'; } template<typename T> ostream& operator<<(ostream& os, const fast_set<T>& s) { os << '['; if (s.size()) { os << *s.begin(); for (auto i = ++s.begin(); i != s.end(); i++) os << ", " << (*i); } return os << ']'; } template<typename T> ostream& operator<<(ostream& os, const multiset<T>& s) { os << '['; if (s.size()) { os << *s.begin(); for (auto i = ++s.begin(); i != s.end(); i++) os << ", " << (*i); } return os << ']'; } template<typename T1, typename T2> ostream& operator<<(ostream& os, const ordered_map<T1, T2>& s) { os << '['; if (s.size()) { os << '(' << s.begin()->FF << " : " << s.begin()->SS << ')'; for (auto i = ++s.begin(); i != s.end(); i++) os << ", " << '(' << i->FF << " : " << i->SS << ')'; } return os << ']'; } template<typename T1, typename T2> ostream& operator<<(ostream& os, const fast_map<T1, T2>& s) { os << '['; if (s.size()) { os << '(' << s.begin()->FF << " : " << s.begin()->SS << ')'; for (auto i = ++s.begin(); i != s.end(); i++) os << ", " << '(' << i->FF << " : " << i->SS << ')'; } return os << ']'; } #define fixfloat(d) fixed << setprecision(d) void print() {} template<typename T, typename... U> void print(T F, U... S) { cout << F; print(S...); } void printl() {} template<typename T, typename... U> void printl(T F, U... S) { cout << F << '\n'; printl(S...); } template<typename T> void prints(T F) { cout << F; } template<typename T, typename... U> void prints(T F, U... S) { cout << F << ' '; prints(S...); } void printc(string c) {} template<typename T, typename... U> void printc(const string c, T F, U... S) { cout << F << c; printc(c, S...); } void println() { cout << '\n'; } template<typename T, typename... U> void println(T F, U... S) { cout << F << ' '; println(S...); } template<typename T, size_t sz> void print(array<T, sz>& a, string s = " ", string e = "\n") { for (int i = 0; i < a.size(); i++) print(a[i], s); print(e); } template<typename T, size_t sz> void print(array<T, sz> a, int n, string s = " ", string e = "\n") { assert(0 <= n && n <= a.size()); for (int i = 0; i < n; i++) print(a[i], s); print(e); } template<typename T, size_t sz> void print(array<T, sz> a, int l, int r, string s = " ", string e = "\n") { assert(0 <= l && l < r && r < a.size()); for (int i = l; i <= r; i++) print(a[i], s); print(e); } template<typename T> void print(vector<T>& v, string s = " ", string e = "\n") { for (int i = 0; i < v.size(); i++) print(v[i], s); print(e); } template<typename T> void print(vector<T>& v, int n, string s = " ", string e = "\n") { assert(0 <= n && n <= v.size()); for (int i = 0; i < n; i++) print(v[i], s); print(e); } template<typename T> void print(vector<T>& v, int l, int r, string s = " ", string e = "\n") { assert(0 <= l && l <= r && r < v.size()); for (int i = l; i <= r; i++) print(v[i], s); print(e); } template<typename T> void print(ordered_set<T>& v, string s = " ", string e = "\n") { for (auto x : v) print(x, s); print(e); } template<typename T> void print(fast_set<T>& v, string s = " ", string e = "\n") { for (auto x : v) print(x, s); print(e); } } using namespace output; namespace debugs { // https://codeforces.com/blog/entry/91347 #define debug(...) logger(__PRETTY_FUNCTION__, __LINE__, #__VA_ARGS__, __VA_ARGS__) template<typename ...Args> void logger(string function, int line, string vars, Args&&... values) { print(function, " - (line: ", line, "): {", vars, "} = {"); string delim = ""; (..., (print(delim, values), delim = ", ")); printl("}"); } } using namespace debugs; } using namespace dutinmeow; //#define USACO 1 //#define FILEIO 1 #if !defined(USACO) #pragma GCC optimize("Ofast") #pragma GCC optimization ("unroll-loops") #pragma GCC target("avx,avx2,fma") #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,tune=native") #endif // code int N, M; vector<int> adj[400005]; array<int, 400005> vis; void dfs(int u, bool is_inf, fast_set<int> &s) { if (s.find(u) != s.end()) is_inf = 1; if (vis[u] != 0) { if (is_inf) { if (vis[u] == -1) return; vis[u] = -1; } else { if (vis[u] == 2 || vis[u] == -1) return; vis[u] = 2; } } else { if (is_inf) vis[u] = -1; else vis[u] = 1; } s.insert(u); for (int v : adj[u]) dfs(v, is_inf, s); //cout << u << " : " << is_inf << ',' << s << " : " << vis[u] << '\n'; s.erase(u); } void solve() { read(N, M); for (int i = 0; i < M; i++) { int a, b; read(a, b); adj[a].PB(b); } fast_set<int> s; dfs(1, 0, s); for (int i = 1; i <= N; i++) cout << vis[i] << ' '; cout << '\n'; for (int i = 1; i <= N; i++) { vis[i] = 0; adj[i].clear(); } } signed main(void) { ios_base::sync_with_stdio(0); cin.tie(0); #ifdef USACO const string ___filename___ = ""; filein(___filename___ + ".in"); fileout(___filename___ + ".out"); #endif #ifdef FILIO filein("input.txt"); fileout("output.txt"); fileerr("error.txt"); #endif int T = 1; read(T); for (int t = 1; t <= T; t++) { // print("Case #", t, ": "); solve(); } }
语法
/* * Created By: 'Present_Sir' * Created On: Saturday 10 July 2021 09:06:11 PM */ #include<bits/stdc++.h> #define int long long using namespace std; int32_t main(){ ios_base::sync_with_stdio(false); cin.tie(NULL); int t; cin >> t; while(t--){ int n, m; cin >> n >> m; vector < vector < int > > gr(n); for(int i=0; i<m; ++i){ int x, y; cin >> x >> y; --x; --y; gr[x].push_back(y); } vector < int > vis(n, 0); set < int > cur_parents; set < int > parents; function < void(int) > dfs = [&](int cur){ vis[cur]++; cur_parents.insert(cur); for(auto x: gr[cur]){ if(vis[x]){ if(cur_parents.find(x)!=cur_parents.end()){ parents.insert(x); }else if(vis[x] == 1){ dfs(x); } }else{ dfs(x); } } cur_parents.erase(cur); return; }; dfs(0); vector < int > ans = vis; function < void(int) > dfs2 = [&](int cur){ vis[cur] = 1; ans[cur] = -1; for(auto x: gr[cur]){ if(vis[x])continue; dfs2(x); } return; }; fill(vis.begin(), vis.end(), 0ll); for(auto x: parents){ dfs2(x); } for(auto x: ans) cout << x << " "; cout << "\n"; } return 0; }
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for(int i = (a); i < (b); ++i) #define sz(x) (int)(x).size() #define all(x) begin(x), end(x) using ll = long long; using pii = pair<int, int>; using vi = vector<int>; void solve() { int n, m; cin >> n >> m; vector<vi> graph(n); for (int i = 0; i < m; ++i) { int u, v; cin >> u >> v; --u; --v; graph[u].push_back(v); } vi res(n, 0); // first do a dfs to find cycles. vi in_stk(n, 0); auto dfs_cyc = [&](auto self, int u) -> void { assert(res[u] == 0); res[u] = 1; in_stk[u] = 1; for (int v : graph[u]) { if (in_stk[v]) { res[u] = res[v] = -1; } else if (res[v] == 0) { self(self, v); } } in_stk[u] = 0; }; dfs_cyc(dfs_cyc, 0); // mark everything reachable from a cycle { queue<int> q; for (int u = 0; u < n; ++u) { if (res[u] == -1) { q.push(u); } } while (!q.empty()) { int u = q.front(); q.pop(); assert(res[u] == -1); for (int v : graph[u]) { if (res[v] != -1) { res[v] = -1; q.push(v); } } } } // now handle multipaths { vi vis2(n, 0); queue<int> q; if (res[0] > 0) { q.push(0); vis2[0] = 1; } while (!q.empty()) { int u = q.front(); q.pop(); for (int v : graph[u]) { if (res[v] == -1) continue; if (vis2[v] && res[v] == 1) { res[v] = 2; q.push(v); } else if (!vis2[v]) { vis2[v] = true; res[v] = res[u]; q.push(v); } } } } for (int i = 0; i < n; ++i) { cout << res[i] << " \n"[i + 1 == n]; } } int main() { cin.tie(0)->sync_with_stdio(0); cin.exceptions(cin.failbit); int T; cin >> T; while (T-- > 0) { solve(); } return 0; }
算法竞赛之路 文章被收录于专栏
整理、记录算法竞赛的好题