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
- #define ld long double
- #define ull unsigned long long
- #define pb push_back
- #define ppb pop_back
- #define mp make_pair
- #define F first
- #define S second
- #define PI 3.1415926535897932384626
- #define sz(x) ((int)(x).size())
- typedef pair<int, int> pii;
- typedef pair<ll, ll> pll;
- typedef vector<int> vi;
- typedef vector<ll> vll;
- typedef vector<ull> vull;
- typedef vector<bool> vb;
- typedef vector<char> vc;
- typedef vector<string> vs;
- typedef vector<pii> vpii;
- typedef vector<pll> vpll;
- typedef vector<vi> vvi;
- typedef vector<vll> vvll;
- typedef vector<vull> vvull;
- typedef vector<vb> vvb;
- typedef vector<vc> vvc;
- typedef vector<vs> vvs;
- /************************************************** DEBUGGER *******************************************************************************************************/
- #ifndef ONLINE_JUDGE
- #define debug(x) cerr << #x <<" "; _print(x); cerr << endl;
- #else
- #define debug(x)
- #endif
- void _print(ll t) { cerr << t; }
- void _print(int t) { cerr << t; }
- void _print(string t) { cerr << t; }
- void _print(char t) { cerr << t; }
- void _print(ld t) { cerr << t; }
- void _print(double t) { cerr << t; }
- void _print(ull t) { cerr << t; }
- template <class T, class V> void _print(pair <T, V> p);
- template <class T> void _print(vector <T> v);
- template <class T> void _print(vector <vector<T>> v);
- template <class T> void _print(set <T> v);
- template <class T, class V> void _print(map <T, V> v);
- template <class T> void _print(multiset <T> v);
- template <class T, class V> void _print(pair <T, V> p) { cerr << "{"; _print(p.F); cerr << ","; _print(p.S); cerr << "}"; }
- template <class T> void _print(vector <T> v) { cerr << "[ "; for (T i : v) {_print(i); cerr << " "; } cerr << "]"; }
- template <class T> void _print(vector <vector<T>> v) { cerr << "==>" << endl; for (vector<T> vec : v) { for(T i : vec) {_print(i); cerr << " "; } cerr << endl; } }
- template <class T> void _print(set <T> v) { cerr << "[ "; for (T i : v) {_print(i); cerr << " "; } cerr << "]"; }
- template <class T> void _print(multiset <T> v) { cerr << "[ "; for (T i : v) {_print(i); cerr << " "; } cerr << "]"; }
- template <class T, class V> void _print(map <T, V> v) { cerr << "[ "; for (auto i : v) {_print(i); cerr << " "; } cerr << "]"; }
- /*******************************************************************************************************************************************************************/
- mt19937_64 rang(chrono::high_resolution_clock::now().time_since_epoch().count());
- int rng(int lim) {
- uniform_int_distribution<int> uid(0,lim-1);
- return uid(rang);
- }
- const int INF = 0x3f3f3f3f;
- const int mod = 1e9+7;
- ll mod_exp(ll a, ll b) { a %= mod; if(a == 0) return 0LL; ll res = 1LL;
- while(b > 0) { if(b & 1) res = (res * a) % mod; a = (a * a) % mod; b >>= 1; } return res; }
- ll mod_inv(ll a) { return mod_exp(a, mod - 2); } // works only for prime value of "mod"
- ll GCD(ll a, ll b) { return (b == 0) ? a : GCD(b, a % b); }
- /******************************************************************************************************************************/
- vvi g;
- // to store all articulation points
- vector<int> point;
- vi wt;
- vb vis;
- int n, m;
- void dfs(int curr, int par, vector<int> &entry, vector<int> &low, int time)
- {
- entry[curr]=low[curr]=time++;
- // for storing the count of #child of the curr node
- // in the DFS Tree (not in the graph)
- int no_of_child=0;
- // now, there are 2 cases
- // 1. if the child is not visited, then visit it
- // and ask for the lowest time of that child
- // 2. if the child is visited and != parent of curr,
- // then backedge is present and therefore cycle is there
- for(auto child: g[curr])
- {
- // case 1
- if(entry[child]==0)
- {
- dfs(child, curr, entry, low, time);
- // increment the #child of curr
- no_of_child++;
- low[curr]=min(low[curr], low[child]);
- // condition for curr to be an articulation pt
- if(par!=-1 && low[child]>=entry[curr])
- point.push_back(curr);
- }
- // case 2
- else if(child != par)
- low[curr]=min(low[curr], entry[child]);
- }
- // separate case for the root of the DFS TREE of the graph
- // to be an articulation pt
- if(par==-1 && no_of_child>=2)
- {
- // the parent of the root of DFS tree was passed as 1
- point.push_back(curr);
- }
- return;
- }
- void artpts_and_bridges()
- {
- // to store the entry/discovery time of all vertices
- // while DFS traversal, it will also be used as visited array
- vector<int> entry(n, 0);
- // to store the lowest time of all the vertices
- vector<int> low(n, 0);
- // initialising the time as 1
- int time=1;
- for(int i = 0; i < n; i++)
- {
- // if not visited yet, call dfs by taking
- // i as the root of the current DFS traversal
- if(entry[i]==0)
- dfs(i, -1, entry, low, time);
- }
- }
- void dfs_(int cur, ll &x, int ap) {
- vis[cur] = 1;
- x += wt[cur];
- for(auto child: g[cur]) {
- if(!vis[child] and child != ap) dfs_(child, x, ap);
- }
- }
- void solve()
- {
- cin >> n >> m;
- g.clear(); g.resize(n);
- point.clear();
- wt.clear(); wt.resize(n);
- vis.clear(); vis.resize(n, 0);
- for(int i = 0; i < n; i++) cin >> wt[i];
- for(int i = 0; i < m; i++) {
- int x, y; cin >> x >> y;
- x -= 1, y -= 1;
- g[x].pb(y); g[y].pb(x);
- }
- artpts_and_bridges();
- ll sum = accumulate(wt.begin(), wt.end(), 0LL);
- if(sz(point) == 0) {
- int mx = *max_element(wt.begin(), wt.end());
- cout << 0 << " " << sum - mx << "\n";
- }
- else {
- vpii tmp;
- for(int i = 0; i < sz(point); i++) tmp.pb({wt[point[i]], point[i]});
- sort(tmp.begin(), tmp.end());
- vis[tmp[0].S] = 1;
- vll comp1;
- for(int i = 0; i < n; i++) {
- if(!vis[i] and i != tmp[0].S) {
- ll x = 0LL;
- dfs_(i, x, tmp[0].S);
- comp1.pb(x);
- }
- }
- sort(comp1.rbegin(), comp1.rend());
- if(sz(tmp) > 1) {
- for(int i = 0; i < n; i++) vis[i] = 0;
- vis[tmp[1].S] = 1;
- vll comp2;
- for(int i = 0; i < n; i++) {
- if(!vis[i] and i != tmp[1].S) {
- ll x = 0LL;
- dfs_(i, x, tmp[1].S);
- comp2.pb(x);
- }
- }
- sort(comp2.rbegin(), comp2.rend());
- if(comp1[1] > comp2[1]) cout << comp1[1] << " " << comp1[0] << "\n";
- else if(comp1[1] < comp2[1]) cout << comp2[1] << " " << comp2[0] << "\n";
- else {
- cout << comp1[1] << " ";
- if(comp1[0] < comp2[0]) cout << comp1[0] << "\n";
- else cout << comp2[0] << "\n";
- }
- }
- else cout << comp1[1] << " " << comp1[0] << "\n";
- }
- }
- int main()
- {
- ios_base::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
- srand(chrono::high_resolution_clock::now().time_since_epoch().count());
- // #ifndef ONLINE_JUDGE
- // freopen("input.txt", "r", stdin);
- // freopen("output.txt", "w", stdout);
- // #endif
- // #ifndef ONLINE_JUDGE
- // freopen("error.txt", "w", stderr);
- // #endif
- int t = 1;
- // int test = 1;
- cin >> t;
- while(t--) {
- // cout << "Case #" << test++ << ": ";
- solve();
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement