Advertisement
fooker

P1900E

Mar 29th, 2024
798
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.23 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. #define ll long long
  4.  
  5. const ll nmax = 1e9+7;
  6. const ll nmax2 = 998244353;
  7.  
  8. #include <ext/pb_ds/assoc_container.hpp>
  9. #include <ext/pb_ds/tree_policy.hpp>
  10. #include <ext/pb_ds/detail/standard_policies.hpp>
  11. using namespace __gnu_pbds;
  12. typedef tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;
  13. typedef tree<std::pair<ll, ll>, null_type, less<std::pair<ll,ll>>, rb_tree_tag, tree_order_statistics_node_update> ordered_set_pair;
  14.  
  15. class DSU {
  16. public:
  17.     std::vector<ll> f, siz;
  18.     DSU(ll n) : f(n + 1), siz(n + 1, 1) {
  19.         std::iota(f.begin() + 1, f.end(), 1);
  20.     }
  21.     ll leader(ll x) {
  22.         while (x != f[x]) x = f[x] = f[f[x]];
  23.         return x;
  24.     }
  25.     bool same(ll x, ll y) {
  26.         return leader(x) == leader(y);
  27.     }
  28.     void merge(ll x, ll y) {
  29.         x = leader(x);
  30.         y = leader(y);
  31.         if (x == y) return;
  32.         siz[x] += siz[y];
  33.         f[y] = x;
  34.     }
  35.     ll size(ll x) {
  36.         return siz[leader(x)];
  37.     }
  38.     void print(ll n){
  39.         std::cout << "first nodes => ";
  40.         for (ll i = 1; i <= n; i++) std::cout << i << " \n"[i == n];
  41.         std::cout << "leader nodes => ";
  42.         for (ll i = 1; i <= n; i++) std::cout << leader(i) << " \n"[i == n];
  43.         std::cout << "size components => ";
  44.         for (ll i = 1; i <= n; i++) std::cout << siz[i] << " \n"[i == n];
  45.     }
  46. };
  47.  
  48. template<class T>
  49. constexpr T power(T a, ll b){
  50.     T res {1};
  51.     for (; b; b /= 2, a *= a){
  52.         if (b % 2){
  53.             res *= a;
  54.         }
  55.     }
  56.     return res;
  57. }
  58.  
  59. constexpr ll mul(ll a, ll b, ll p) {
  60.     ll res = a * b - (ll)(1.L * a * b / p) * p;
  61.     res %= p;
  62.     if (res < 0) {
  63.         res += p;
  64.     }
  65.     return res;
  66. }
  67.  
  68. template<ll P>
  69. struct modint {
  70.     ll x;
  71.     constexpr modint() : x {0} {}
  72.     constexpr modint(ll y) : x {norm(y % getmod())} {}
  73.  
  74.     static ll mod;
  75.     constexpr static ll getmod() {
  76.         if (P > 0) {
  77.             return P;
  78.         } else {
  79.             return mod;
  80.         }
  81.     }
  82.     constexpr static void setmod(ll newmod) {
  83.         mod = newmod;
  84.     }
  85.     constexpr ll norm(ll x) const {
  86.         if (x < 0) {
  87.             x += getmod();
  88.         }
  89.         if (x >= getmod()) {
  90.             x -= getmod();
  91.         }
  92.         return x;
  93.     }
  94.     constexpr ll val() const {
  95.         return x;
  96.     }
  97.  
  98.     constexpr modint operator-() const {
  99.         modint res;
  100.         res.x = norm(getmod() - x);
  101.         return res;
  102.     }
  103.     constexpr modint inv() const {
  104.         return power(*this, getmod() - 2);
  105.     }
  106.     constexpr modint &operator*=(modint rhs) & {
  107.         if (getmod() < (1ULL << 31)) {
  108.             x = x * rhs.x % int(getmod());
  109.         } else {
  110.             x = mul(x, rhs.x, getmod());
  111.         }
  112.         return *this;
  113.     }
  114.     constexpr modint &operator+=(modint rhs) & {
  115.         x = norm(x + rhs.x);
  116.         return *this;
  117.     }
  118.     constexpr modint &operator-=(modint rhs) & {
  119.         x = norm(x - rhs.x);
  120.         return *this;
  121.     }
  122.     constexpr modint &operator/=(modint rhs) & {
  123.         return *this *= rhs.inv();
  124.     }
  125.     friend constexpr modint operator*(modint lhs, modint rhs) {
  126.         modint res = lhs;
  127.         res *= rhs;
  128.         return res;
  129.     }
  130.     friend constexpr modint operator+(modint lhs, modint rhs) {
  131.         modint res = lhs;
  132.         res += rhs;
  133.         return res;
  134.     }
  135.     friend constexpr modint operator-(modint lhs, modint rhs) {
  136.         modint res = lhs;
  137.         res -= rhs;
  138.         return res;
  139.     }
  140.     friend constexpr modint operator/(modint lhs, modint rhs) {
  141.         modint res = lhs;
  142.         res /= rhs;
  143.         return res;
  144.     }
  145.     friend constexpr std::istream &operator>>(std::istream &is, modint &a) {
  146.         ll v;
  147.         is >> v;
  148.         a = modint(v);
  149.         return is;
  150.     }
  151.     friend constexpr std::ostream &operator<<(std::ostream &os, const modint &a) {
  152.         return os << a.val();
  153.     }
  154.     friend constexpr bool operator==(modint lhs, modint rhs ){
  155.         return lhs.val() == rhs.val();
  156.     }
  157.     friend constexpr bool operator!=(modint lhs, modint rhs) {
  158.         return lhs.val() != rhs.val();
  159.     }
  160. };
  161.  
  162. template<>
  163. ll modint<0>::mod = 1e9;
  164. using mm = modint<0>;
  165.  
  166. void solve() {
  167.     ll n, m;
  168.     std::cin >> n >> m;
  169.  
  170.     ll a[n + 1];
  171.     for (ll i = 1; i <= n; i++) std::cin >> a[i];
  172.  
  173.     std::vector<ll> adj[n + 1];
  174.     std::vector<ll> adjr[n + 1];
  175.     for (ll i = 1, x, y; i <= m; i++) {
  176.         std::cin >> x >> y;
  177.         adj[x].push_back(y);
  178.         adjr[y].push_back(x);
  179.     }
  180.  
  181.     bool vis[n + 1];
  182.     for (ll i = 1; i <= n; i++) vis[i] = false;
  183.    
  184.     std::vector<ll> components(n + 1);
  185.     std::vector<ll> topsort;
  186.  
  187.     std::function<void(ll, ll)> dfs1 = [&] (ll u, ll p) {
  188.         vis[u] = true;
  189.         for (auto v: adj[u]) {
  190.             if (v == p) continue;
  191.             if (vis[v]) continue;
  192.             dfs1(v, u);
  193.         }
  194.         topsort.push_back(u);
  195.     };
  196.    
  197.     for (ll i = 1; i <= n; i++) {
  198.         if (!vis[i]) {
  199.             dfs1(i, 0);
  200.         }
  201.     }
  202.  
  203.     std::reverse(topsort.begin(), topsort.end());
  204.  
  205.     for (ll i = 1; i <= n; i++) vis[i] = false;
  206.  
  207.     ll id = 1;
  208.  
  209.     std::function<void(ll, ll)> dfs2 = [&] (ll u, ll p) {
  210.         vis[u] = true;
  211.  
  212.         for (auto v: adjr[u]) {
  213.             if (v == p) continue;
  214.             if (vis[v]) continue;
  215.  
  216.             dfs2(v, u);
  217.         }
  218.  
  219.         components[u] = id;
  220.     };
  221.  
  222.     for (auto u: topsort) {
  223.         if (!vis[u]) {
  224.             dfs2(u, 0);
  225.             id++;
  226.         }
  227.     }
  228.  
  229.     std::vector<ll> new_graph[id];
  230.     std::vector<ll> dist(id);
  231.     std::vector<ll> cost(id);
  232.     std::vector<ll> sz(id);
  233.  
  234.     for (ll i = 1; i <= n; i++) {
  235.         cost[components[i]] += a[i];
  236.         sz[components[i]]++;
  237.     }
  238.  
  239.     std::vector<ll> dp(id, LLONG_MAX);
  240.     std::queue<ll> q;
  241.  
  242.     std::vector<ll> indegree(id);
  243.  
  244.     for (ll i = 1; i <= n; i++) {
  245.         for (auto u: adj[i]) {
  246.             if (components[u] != components[i]) {
  247.                 new_graph[components[i]].push_back(components[u]);
  248.                 indegree[components[u]]++;
  249.             }
  250.         }
  251.     }
  252.  
  253.     for (ll i = 1; i < id; i++) {
  254.         if (indegree[i]) {
  255.             q.push(i);
  256.             dist[i] = sz[i];
  257.             dp[i] = cost[i];
  258.         }
  259.     }
  260.  
  261.     ll c = 0;
  262.  
  263.     while (q.size()) {
  264.         auto s = q.front();
  265.         q.pop();
  266.  
  267.         c++;
  268.         for (auto u: new_graph[s]) {
  269.  
  270.             if (dist[u] < dist[s] + sz[s]) {
  271.                 dist[u] = dist[s] + sz[s];
  272.                 dp[u] = std::min(dp[u], dp[s] + cost[u]);
  273.             }
  274.  
  275.             indegree[u]--;
  276.             if (indegree[u] == 0) {
  277.                 q.push(u);
  278.             }
  279.         }
  280.     }
  281.  
  282.     ll ans1 = 0;
  283.     for (ll i = 1; i < id; i++) {
  284.         ans1 = std::max(ans1, dist[i]);
  285.     }
  286.  
  287.     ll ans2 = LLONG_MAX;
  288.     for (ll i = 1; i < id; i++) {
  289.         if (dist[i] == ans1) {
  290.             ans2 = std::min(ans2, dp[i]);
  291.         }
  292.     }
  293.  
  294.     std::cout << ans1 << ' ' << ans2 << '\n';
  295. }
  296.  
  297. int main(){
  298.     std::ios_base::sync_with_stdio(false);
  299.     std::cin.tie(0);
  300.     std::cout.tie(0);
  301.  
  302.     int t;
  303.     std::cin >> t;
  304.     while(t--) {
  305.         solve();
  306.     }
  307. }
  308.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement