#include <cstdio> #include <vector> #include <utility> #include <algorithm> using namespace std; #define st first #define nd second const int N = 200005; vector <pair<int,int> > zap[N]; int ojc[2*N][20], n; int G[N], lev[2*N], tab[N], fu[2*N]; int fuf(int a) { if (fu[a]==a) return a; fu[a] = fuf( fu[a] ); return fu[a]; } void fuu(int a,int b) { fu[ fuf(a) ] = fuf(b); } bool cmp(int a,int b) { // if (lev[a] == lev[b]) return a<b; return lev[a] > lev[b]; } int level(int a) { if (ojc[a][0]==a) return 0; if (lev[a]) return lev[a]; lev[a] = level( ojc[a][0] ) + 1; return lev[a]; } int ojciec(int a,int k) { for (int i=18;i>=0;i--) if ( (1<<i)&k ) a = ojc[a][i]; return a; } int lca(int a,int b) { if ( lev[a] > lev[b] ) swap(a,b); b = ojciec(b, lev[b] - lev[a] ); if (a==b) return a; for (int i=18;i>=0;i--) if (ojc[a][i] != ojc[b][i]) { a = ojc[a][i]; b = ojc[b][i]; } if (ojc[a][0]==ojc[b][0]) return ojc[a][0]; return n; } long long int wynik; int main() { int m,k,a,b,x; scanf("%d%d%d",&n,&m,&k); for (int i=1;i<=n;i++) scanf("%d",&G[i] ); for (int i=1;i<=n+m;i++) ojc[i][0] = fu[i]=i; for (int i=1;i<=m;i++) { scanf("%d%d",&a,&b); ojc[ fuf(a) ][0] = ojc[ fuf(b) ][0] = n+i; fuu( a, n+i ); fuu( b, n+i ); } for (int z=1;z<19;z++) for (int i=1;i<=n+m;i++) ojc[i][z] = ojc[ ojc[i][z-1] ][z-1]; for (int i=1;i<=n+m;i++) level(i); for (int i=0;i<k;i++) { scanf("%d%d",&a,&b); // printf("lca %d %d - %d\n",a,b,lca(a,b) ); zap[ lca(a,b) - n ].push_back( make_pair(a,b) ); } for (int i=0;i<n;i++) tab[i]= n+i+1; sort( tab, tab+n, cmp); for (int i=0;i<n;i++) { a = tab[i] - n; for (int z=0;z<zap[ a ].size();z++) { x = min( G[ zap[ a ][z].first ], G[ zap[ a ][z].second ] ); wynik += x * 2; G[ zap[ a ][z].first ] -= x; G[ zap[ a ][z].second ] -= x; } } printf("%lld\n",wynik); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | #include <cstdio> #include <vector> #include <utility> #include <algorithm> using namespace std; #define st first #define nd second const int N = 200005; vector <pair<int,int> > zap[N]; int ojc[2*N][20], n; int G[N], lev[2*N], tab[N], fu[2*N]; int fuf(int a) { if (fu[a]==a) return a; fu[a] = fuf( fu[a] ); return fu[a]; } void fuu(int a,int b) { fu[ fuf(a) ] = fuf(b); } bool cmp(int a,int b) { // if (lev[a] == lev[b]) return a<b; return lev[a] > lev[b]; } int level(int a) { if (ojc[a][0]==a) return 0; if (lev[a]) return lev[a]; lev[a] = level( ojc[a][0] ) + 1; return lev[a]; } int ojciec(int a,int k) { for (int i=18;i>=0;i--) if ( (1<<i)&k ) a = ojc[a][i]; return a; } int lca(int a,int b) { if ( lev[a] > lev[b] ) swap(a,b); b = ojciec(b, lev[b] - lev[a] ); if (a==b) return a; for (int i=18;i>=0;i--) if (ojc[a][i] != ojc[b][i]) { a = ojc[a][i]; b = ojc[b][i]; } if (ojc[a][0]==ojc[b][0]) return ojc[a][0]; return n; } long long int wynik; int main() { int m,k,a,b,x; scanf("%d%d%d",&n,&m,&k); for (int i=1;i<=n;i++) scanf("%d",&G[i] ); for (int i=1;i<=n+m;i++) ojc[i][0] = fu[i]=i; for (int i=1;i<=m;i++) { scanf("%d%d",&a,&b); ojc[ fuf(a) ][0] = ojc[ fuf(b) ][0] = n+i; fuu( a, n+i ); fuu( b, n+i ); } for (int z=1;z<19;z++) for (int i=1;i<=n+m;i++) ojc[i][z] = ojc[ ojc[i][z-1] ][z-1]; for (int i=1;i<=n+m;i++) level(i); for (int i=0;i<k;i++) { scanf("%d%d",&a,&b); // printf("lca %d %d - %d\n",a,b,lca(a,b) ); zap[ lca(a,b) - n ].push_back( make_pair(a,b) ); } for (int i=0;i<n;i++) tab[i]= n+i+1; sort( tab, tab+n, cmp); for (int i=0;i<n;i++) { a = tab[i] - n; for (int z=0;z<zap[ a ].size();z++) { x = min( G[ zap[ a ][z].first ], G[ zap[ a ][z].second ] ); wynik += x * 2; G[ zap[ a ][z].first ] -= x; G[ zap[ a ][z].second ] -= x; } } printf("%lld\n",wynik); } |