// https://judge.yosupo.jp/submission/162559 #ifndef LOCAL #pragma GCC optimize ("Ofast") #pragma GCC optimize ("unroll-loops") #endif #include using namespace std; using ll=long long; #define int ll #define rng(i,a,b) for(int i=int(a);i=int(a);i--) #define per(i,b) gnr(i,0,b) #define pb push_back #define eb emplace_back #define a first #define b second #define bg begin() #define ed end() #define all(x) x.bg,x.ed #define si(x) int(x.size()) #ifdef LOCAL #define dmp(x) cerr<<__LINE__<<" "<<#x<<" "< bool chmax(t&a,u b){if(a bool chmin(t&a,u b){if(b using vc=vector; template using vvc=vc>; using pi=pair; using vi=vc; template ostream& operator<<(ostream& os,const pair& p){ return os<<"{"< ostream& operator<<(ostream& os,const vc& v){ os<<"{"; for(auto e:v)os< void dmpr(ostream&os,const T&t,const Args&... args){ os< ostream& operator<<(ostream&os,const array&a){ return os<(all(a)); } template void print_tuple(ostream&,const T&){ } template void print_tuple(ostream&os,const T&t){ if(i)os<<","; os<(t); print_tuple(os,t); } template ostream& operator<<(ostream&os,const tuple&t){ os<<"{"; print_tuple<0,tuple,Args...>(os,t); return os<<"}"; } ll read(){ ll i; cin>>i; return i; } vi readvi(int n,int off=0){ vi v(n); rep(i,n)v[i]=read()+off; return v; } pi readpi(int off=0){ int a,b;cin>>a>>b; return pi(a+off,b+off); } template void print_single(t x,int suc=1){ cout< void print_single(const pair&p,int suc=1){ print_single(p.a,2); print_single(p.b,suc); } template void print_single(const vector&v,int suc=1){ rep(i,v.size()) print_single(v[i],i==int(v.size())-1?suc:2); } template void print_offset(const vector&v,ll off,int suc=1){ rep(i,v.size()) print_single(v[i]+off,i==int(v.size())-1?suc:2); } template void print_single(const array&v,int suc=1){ rep(i,N) print_single(v[i],i==int(N)-1?suc:2); } template void print(const T&t){ print_single(t); } template void print(const T&t,const Args&...args){ print_single(t,2); print(args...); } string readString(){ string s; cin>>s; return s; } template T sq(const T& t){ return t*t; } void YES(bool ex=true){ cout<<"YES\n"; if(ex)exit(0); #ifdef LOCAL cout.flush(); #endif } void NO(bool ex=true){ cout<<"NO\n"; if(ex)exit(0); #ifdef LOCAL cout.flush(); #endif } void Yes(bool ex=true){ cout<<"Yes\n"; if(ex)exit(0); #ifdef LOCAL cout.flush(); #endif } void No(bool ex=true){ cout<<"No\n"; if(ex)exit(0); #ifdef LOCAL cout.flush(); #endif } //#define CAPITAL /* void yes(bool ex=true){ #ifdef CAPITAL cout<<"YES"<<"\n"; #else cout<<"Yes"<<"\n"; #endif if(ex)exit(0); #ifdef LOCAL cout.flush(); #endif } void no(bool ex=true){ #ifdef CAPITAL cout<<"NO"<<"\n"; #else cout<<"No"<<"\n"; #endif if(ex)exit(0); #ifdef LOCAL cout.flush(); #endif }*/ void possible(bool ex=true){ #ifdef CAPITAL cout<<"POSSIBLE"<<"\n"; #else cout<<"Possible"<<"\n"; #endif if(ex)exit(0); #ifdef LOCAL cout.flush(); #endif } void impossible(bool ex=true){ #ifdef CAPITAL cout<<"IMPOSSIBLE"<<"\n"; #else cout<<"Impossible"<<"\n"; #endif if(ex)exit(0); #ifdef LOCAL cout.flush(); #endif } constexpr ll ten(int n){ return n==0?1:ten(n-1)*10; } const ll infLL=LLONG_MAX/3; #ifdef int const int inf=infLL; #else const int inf=INT_MAX/2-100; #endif int topbit(signed t){ return t==0?-1:31-__builtin_clz(t); } int topbit(ll t){ return t==0?-1:63-__builtin_clzll(t); } int topbit(ull t){ return t==0?-1:63-__builtin_clzll(t); } int botbit(signed a){ return a==0?32:__builtin_ctz(a); } int botbit(ll a){ return a==0?64:__builtin_ctzll(a); } int botbit(ull a){ return a==0?64:__builtin_ctzll(a); } int popcount(signed t){ return __builtin_popcount(t); } int popcount(ll t){ return __builtin_popcountll(t); } int popcount(ull t){ return __builtin_popcountll(t); } int bitparity(ll t){ return __builtin_parityll(t); } bool ispow2(int i){ return i&&(i&-i)==i; } ll mask(int i){ return (ll(1)< void mkuni(vc&v){ sort(all(v)); v.erase(unique(all(v)),v.ed); } ll rand_int(ll l, ll r) { //[l, r] //#ifdef LOCAL static mt19937_64 gen; /*#else static mt19937_64 gen(chrono::steady_clock::now().time_since_epoch().count()); #endif*/ return uniform_int_distribution(l, r)(gen); } ll rand_int(ll k){ //[0,k) return rand_int(0,k-1); } template void myshuffle(vc&a){ rep(i,si(a))swap(a[i],a[rand_int(0,i)]); } template int lwb(const vc&v,const t&a){ return lower_bound(all(v),a)-v.bg; } template bool bis(const vc&v,const t&a){ return binary_search(all(v),a); } vvc readGraph(int n,int m){ vvc g(n); rep(i,m){ int a,b; cin>>a>>b; //sc.read(a,b); a--;b--; g[a].pb(b); g[b].pb(a); } return g; } vvc readTree(int n){ return readGraph(n,n-1); } template vc presum(const vc&a){ vc s(si(a)+1); rep(i,si(a))s[i+1]=s[i]+a[i]; return s; } vc presum(const vi&a){ vc s(si(a)+1); rep(i,si(a))s[i+1]=s[i]+a[i]; return s; } //BIT で数列を管理するときに使う (CF850C) template vc predif(vc a){ gnr(i,1,si(a))a[i]-=a[i-1]; return a; } template vvc imos(const vvc&a){ int n=si(a),m=si(a[0]); vvc b(n+1,vc(m+1)); rep(i,n)rep(j,m) b[i+1][j+1]=b[i+1][j]+b[i][j+1]-b[i][j]+a[i][j]; return b; } //verify してないや void transvvc(int&n,int&m){ swap(n,m); } template void transvvc(int&n,int&m,vvc&a,Args&...args){ assert(si(a)==n); vvc b(m,vi(n)); rep(i,n){ assert(si(a[i])==m); rep(j,m)b[j][i]=a[i][j]; } a.swap(b); transvvc(n,m,args...); } //CF854E void rotvvc(int&n,int&m){ swap(n,m); } template void rotvvc(int&n,int&m,vvc&a,Args&...args){ assert(si(a)==n); vvc b(m,vi(n)); rep(i,n){ assert(si(a[i])==m); rep(j,m)b[m-1-j][i]=a[i][j]; } a.swap(b); rotvvc(n,m,args...); } //ソートして i 番目が idx[i] //CF850C template vi sortidx(const vc&a){ int n=si(a); vi idx(n);iota(all(idx),0); sort(all(idx),[&](int i,int j){return a[i] vc a_idx(const vc&a,const vi&idx){ int n=si(a); assert(si(idx)==n); vc vs(n); rep(i,n)vs[i]=a[idx[i]]; return vs; } //CF850C vi invperm(const vi&p){ int n=si(p); vi q(n); rep(i,n)q[p[i]]=i; return q; } template s SUM(const vc&a){ return accumulate(all(a),s(0)); } template t MAX(const vc&a){ return *max_element(all(a)); } template pair MAXi(const vc&a){ auto itr=max_element(all(a)); return mp(*itr,itr-a.bg); } template t MIN(const vc&a){ return *min_element(all(a)); } template pair MINi(const vc&a){ auto itr=min_element(all(a)); return mp(*itr,itr-a.bg); } template pair operator+(const pair&a,const pair&b){ return mp(a.a+b.a,a.b+b.b); } vi vid(int n){ vi res(n);iota(all(res),0); return res; } template void rein(S&s){ reverse(all(s)); } template S reout(S s){ rein(s); return s; } pi operator+(pi a,pi b){return pi(a.a+b.a,a.b+b.b);} template t gpp(vc&vs){ assert(si(vs)); t res=move(vs.back()); vs.pop_back(); return res; } template void pb(vc&a,const vc&b){ a.insert(a.ed,all(b)); } template vc cat(vc a,const vc&b){ pb(a,b); return a; } template vc& operator+=(vc&a,u x){ for(auto&v:a)v+=x; return a; } template vc operator+(vc a,u x){ return a+=x; } template vc& operator-=(vc&a,u x){ for(auto&v:a)v-=x; return a; } template vc& operator-(vc a,u x){ return a-=x; } //VERIFY: yosupo //KUPC2017J //AOJDSL1A //without rank struct unionfind{ vi p,s; int c; unionfind(int n):p(n,-1),s(n,1),c(n){} void clear(){ fill(all(p),-1); fill(all(s),1); c=si(p); } int find(int a){ return p[a]==-1?a:(p[a]=find(p[a])); } //set b to a child of a bool unite(int a,int b){ a=find(a); b=find(b); if(a==b)return false; p[b]=a; s[a]+=s[b]; c--; return true; } bool same(int a,int b){ return find(a)==find(b); } int sz(int a){ return s[find(a)]; } }; bool dbg=false; //ATC002 C //F(a,b) -> b を選択 //普通の priority_queue と同じ (less で max が取れる) template struct leftistheaplazy{ struct N{ T t; U u; N *l,*r; int s; N():t{},u{},l(nullptr),r(nullptr),s(1){} }; using np=N*; const int n; unique_ptr buf; int used; F f; leftistheaplazy(int nn,F ff=F()):n(nn),buf(new N[n]),used(0),f(ff){} np nn(T t){ assert(usedt=t; return res; } int depth(np a){ if(!a)return 0; return a->s; } np add(np a,const U&v){ if(a){ a->t+=v; a->u+=v; } return a; } np sub(np a,const U&v){ if(a){ a->t-=v; a->u-=v; } return a; } np merge(np a,np b){ if(!a)return b; if(!b)return a; if(f(a->t,b->t))swap(a,b); a->r=merge(a->r,sub(b,a->u)); if(depth(a->l)r)) swap(a->l,a->r); a->s=depth(a->r)+1; return a; } void meld(np&a,np b){ a=merge(a,b); } T pop(np&a){ T res=a->t; a=merge(add(a->l,a->u),add(a->r,a->u)); return res; } }; //union find の unite で a,b の順番保持するのが必要 //AOJGRL2B //yosupo judge //others->root template struct dirmst{ struct E{ int to,id; D cost; bool operator>(const E&e)const{ return cost>e.cost; } E&operator+=(const D&d){ cost+=d; return *this; } E&operator-=(const D&d){ cost-=d; return *this; } }; int n; vc> es; dirmst(int nn):n(nn){} void ae(int s,int t,D d){ es.eb(s,t,d); } //cost,edge-list pair calc(int rt){ int m=si(es); leftistheaplazy,D> h(m); using np=typename decltype(h)::np; vc g(n+m); rep(i,m){ auto [s,t,d]=es[i]; h.meld(g[s],h.nn({t,i,d})); } vi st(n+m); st[rt]=2; vc best(n+m); vi p(n+m,-1); unionfind uf(n+m); D ans{}; int tail=n; rep(i,n)if(st[i]==0){ vi vs{i}; while(1){ int a=vs.back(); assert(st[a]==0); st[a]=1; if(!g[a]){ assert(false); //答えが存在しなければ,{-1,{}} を返すはず(未検証) //return mp(-1,vi{}); } E e=h.pop(g[a]); best[a]=e; ans+=e.cost; int to=uf.find(e.to); if(st[to]==0){ vs.pb(to); }else if(st[to]==1){ int r=si(vs),l=r-1; while(vs[l]!=to) l--; int v=tail++; rng(j,l,r){ h.meld(g[v],h.sub(g[vs[j]],best[vs[j]].cost)); p[vs[j]]=v; uf.unite(v,vs[j]); } vs.resize(l); vs.pb(v); }else if(st[to]==2){ break; }else{ assert(false); } } for(auto v:vs) st[v]=2; } //union-find の過程の木の根の方から辺を採用していく vi ls; vc done(tail); done[rt]=true; per(v,tail)if(!done[v]){ ls.pb(best[v].id); auto [s,t,d]=es[best[v].id]; while(s!=-1&&!done[s]){ done[s]=true; s=p[s]; } } return make_pair(ans,ls); } }; void slv(){ int n,m,s; if(dbg){ static int itr=0; itr++; int T=10000; if(itr%T==0)cerr<>n>>m>>s; } dirmst d(n); vc es; rep(i,m){ int a,b,c; if(dbg){ a=rand_int(n); b=rand_int(n); c=rand_int(1,2); }else{ cin>>a>>b>>c; } es.eb(b,a); d.ae(b,a,c); } auto [ans,ls]=d.calc(s); if(dbg){ }else{ print(ans); vi p(n,s); for(auto i:ls) p[es[i].a]=es[i].b; print(p); } } /* signed main(){ cin.tie(0); ios::sync_with_stdio(0); cout<>t;rep(_,t) slv(); } } */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; using Int = long long; // template ostream &operator<<(ostream &os, const vector &as); // template ostream &operator<<(ostream &os, const pair &a) { return os << "(" << a.first << ", " << a.second << ")"; }; // template ostream &operator<<(ostream &os, const vector &as) { const int sz = as.size(); os << "["; for (int i = 0; i < sz; ++i) { if (i >= 256) { os << ", ..."; break; } if (i > 0) { os << ", "; } os << as[i]; } return os << "]"; } template void pv(T a, T b) { for (T i = a; i != b; ++i) cerr << *i << " "; cerr << endl; } template bool chmin(T &t, const T &f) { if (t > f) { t = f; return true; } return false; } template bool chmax(T &t, const T &f) { if (t < f) { t = f; return true; } return false; } #define COLOR(s) ("\x1b[" s "m") #undef int int N, M; vector C; vector A, B; int main() { for (int numCases; ~scanf("%d", &numCases); ) { for (int caseId = 1; caseId <= numCases; ++caseId) { scanf("%d%d", &N, &M); C.resize(N); for (int u = 0; u < N; ++u) scanf("%lld", &C[u]); A.resize(M); B.resize(M); for (int i = 0; i < M; ++i) { scanf("%d%d", &A[i], &B[i]); --A[i]; --B[i]; } dirmst d(N + 1); for (int u = 0; u < N; ++u) { d.ae(u, N, 0); } for (int i = 0; i < M; ++i) { d.ae(A[i], B[i], -C[B[i]]); d.ae(B[i], A[i], -C[A[i]]); } const auto [ans,ls]=d.calc(N); printf("%lld\n", -ans); } #ifndef LOCAL break; #endif } return 0; }