Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- #define ll long long
- const ll nmax = 1e9+7;
- const ll nmax2 = 998244353;
- #include <ext/pb_ds/assoc_container.hpp>
- #include <ext/pb_ds/tree_policy.hpp>
- #include <ext/pb_ds/detail/standard_policies.hpp>
- using namespace __gnu_pbds;
- typedef tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;
- typedef tree<std::pair<ll, ll>, null_type, less<std::pair<ll,ll>>, rb_tree_tag, tree_order_statistics_node_update> ordered_set_pair;
- class DSU {
- public:
- std::vector<ll> f, siz;
- DSU(ll n) : f(n + 1), siz(n + 1, 1) {
- std::iota(f.begin() + 1, f.end(), 1);
- }
- ll leader(ll x) {
- while (x != f[x]) x = f[x] = f[f[x]];
- return x;
- }
- bool same(ll x, ll y) {
- return leader(x) == leader(y);
- }
- void merge(ll x, ll y) {
- x = leader(x);
- y = leader(y);
- if (x == y) return;
- siz[x] += siz[y];
- f[y] = x;
- }
- ll size(ll x) {
- return siz[leader(x)];
- }
- void print(ll n){
- std::cout << "first nodes => ";
- for (ll i = 1; i <= n; i++) std::cout << i << " \n"[i == n];
- std::cout << "leader nodes => ";
- for (ll i = 1; i <= n; i++) std::cout << leader(i) << " \n"[i == n];
- std::cout << "size components => ";
- for (ll i = 1; i <= n; i++) std::cout << siz[i] << " \n"[i == n];
- }
- };
- template<class T>
- constexpr T power(T a, ll b){
- T res {1};
- for (; b; b /= 2, a *= a){
- if (b % 2){
- res *= a;
- }
- }
- return res;
- }
- constexpr ll mul(ll a, ll b, ll p) {
- ll res = a * b - (ll)(1.L * a * b / p) * p;
- res %= p;
- if (res < 0) {
- res += p;
- }
- return res;
- }
- template<ll P>
- struct modint {
- ll x;
- constexpr modint() : x {0} {}
- constexpr modint(ll y) : x {norm(y % getmod())} {}
- static ll mod;
- constexpr static ll getmod() {
- if (P > 0) {
- return P;
- } else {
- return mod;
- }
- }
- constexpr static void setmod(ll newmod) {
- mod = newmod;
- }
- constexpr ll norm(ll x) const {
- if (x < 0) {
- x += getmod();
- }
- if (x >= getmod()) {
- x -= getmod();
- }
- return x;
- }
- constexpr ll val() const {
- return x;
- }
- constexpr modint operator-() const {
- modint res;
- res.x = norm(getmod() - x);
- return res;
- }
- constexpr modint inv() const {
- return power(*this, getmod() - 2);
- }
- constexpr modint &operator*=(modint rhs) & {
- if (getmod() < (1ULL << 31)) {
- x = x * rhs.x % int(getmod());
- } else {
- x = mul(x, rhs.x, getmod());
- }
- return *this;
- }
- constexpr modint &operator+=(modint rhs) & {
- x = norm(x + rhs.x);
- return *this;
- }
- constexpr modint &operator-=(modint rhs) & {
- x = norm(x - rhs.x);
- return *this;
- }
- constexpr modint &operator/=(modint rhs) & {
- return *this *= rhs.inv();
- }
- friend constexpr modint operator*(modint lhs, modint rhs) {
- modint res = lhs;
- res *= rhs;
- return res;
- }
- friend constexpr modint operator+(modint lhs, modint rhs) {
- modint res = lhs;
- res += rhs;
- return res;
- }
- friend constexpr modint operator-(modint lhs, modint rhs) {
- modint res = lhs;
- res -= rhs;
- return res;
- }
- friend constexpr modint operator/(modint lhs, modint rhs) {
- modint res = lhs;
- res /= rhs;
- return res;
- }
- friend constexpr std::istream &operator>>(std::istream &is, modint &a) {
- ll v;
- is >> v;
- a = modint(v);
- return is;
- }
- friend constexpr std::ostream &operator<<(std::ostream &os, const modint &a) {
- return os << a.val();
- }
- friend constexpr bool operator==(modint lhs, modint rhs ){
- return lhs.val() == rhs.val();
- }
- friend constexpr bool operator!=(modint lhs, modint rhs) {
- return lhs.val() != rhs.val();
- }
- };
- template<>
- ll modint<0>::mod = 1e9;
- using mm = modint<0>;
- void solve() {
- ll n, m;
- std::cin >> n >> m;
- ll a[n + 1];
- for (ll i = 1; i <= n; i++) std::cin >> a[i];
- std::vector<ll> adj[n + 1];
- std::vector<ll> adjr[n + 1];
- for (ll i = 1, x, y; i <= m; i++) {
- std::cin >> x >> y;
- adj[x].push_back(y);
- adjr[y].push_back(x);
- }
- bool vis[n + 1];
- for (ll i = 1; i <= n; i++) vis[i] = false;
- std::vector<ll> components(n + 1);
- std::vector<ll> topsort;
- std::function<void(ll, ll)> dfs1 = [&] (ll u, ll p) {
- vis[u] = true;
- for (auto v: adj[u]) {
- if (v == p) continue;
- if (vis[v]) continue;
- dfs1(v, u);
- }
- topsort.push_back(u);
- };
- for (ll i = 1; i <= n; i++) {
- if (!vis[i]) {
- dfs1(i, 0);
- }
- }
- std::reverse(topsort.begin(), topsort.end());
- for (ll i = 1; i <= n; i++) vis[i] = false;
- ll id = 1;
- std::function<void(ll, ll)> dfs2 = [&] (ll u, ll p) {
- vis[u] = true;
- for (auto v: adjr[u]) {
- if (v == p) continue;
- if (vis[v]) continue;
- dfs2(v, u);
- }
- components[u] = id;
- };
- for (auto u: topsort) {
- if (!vis[u]) {
- dfs2(u, 0);
- id++;
- }
- }
- std::vector<ll> new_graph[id];
- std::vector<ll> dist(id);
- std::vector<ll> cost(id);
- std::vector<ll> sz(id);
- for (ll i = 1; i <= n; i++) {
- cost[components[i]] += a[i];
- sz[components[i]]++;
- }
- std::vector<ll> dp(id, LLONG_MAX);
- std::queue<ll> q;
- std::vector<ll> indegree(id);
- for (ll i = 1; i <= n; i++) {
- for (auto u: adj[i]) {
- if (components[u] != components[i]) {
- new_graph[components[i]].push_back(components[u]);
- indegree[components[u]]++;
- }
- }
- }
- for (ll i = 1; i < id; i++) {
- if (indegree[i]) {
- q.push(i);
- dist[i] = sz[i];
- dp[i] = cost[i];
- }
- }
- ll c = 0;
- while (q.size()) {
- auto s = q.front();
- q.pop();
- c++;
- for (auto u: new_graph[s]) {
- if (dist[u] < dist[s] + sz[s]) {
- dist[u] = dist[s] + sz[s];
- dp[u] = std::min(dp[u], dp[s] + cost[u]);
- }
- indegree[u]--;
- if (indegree[u] == 0) {
- q.push(u);
- }
- }
- }
- ll ans1 = 0;
- for (ll i = 1; i < id; i++) {
- ans1 = std::max(ans1, dist[i]);
- }
- ll ans2 = LLONG_MAX;
- for (ll i = 1; i < id; i++) {
- if (dist[i] == ans1) {
- ans2 = std::min(ans2, dp[i]);
- }
- }
- std::cout << ans1 << ' ' << ans2 << '\n';
- }
- int main(){
- std::ios_base::sync_with_stdio(false);
- std::cin.tie(0);
- std::cout.tie(0);
- int t;
- std::cin >> t;
- while(t--) {
- solve();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement