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
103
104
105
106
107
108
109
110
111
112
113
#include <stdio.h>
#include <map>
#include <vector>
using namespace std;
typedef int I;
typedef long long L;

struct P {
  I x;
  I y;
  //void norm() {
  //  if (y>x)
  //    swap(x, y);
  //}
  //friend bool operator<(const P& a, const P& b) {
  //  return a.x < b.x || (a.x == b.x && a.y < b.y);
  //}
};

#define MAXN 200000
#define MAXK 500000

// brute force
I N, M, K;
I fio[MAXN+1];
P ope[MAXN];
P rea[MAXK];

static L brute() {
  if (M == 0 || K ==0)
    return 0;

  typedef map<I, I> Map;
  typedef vector<Map> VMap;

  L osad = 0;
  VMap vmap(N+1);
  // tworzymy mape
  for (I n=1; n<=N; ++n) {
    I k = fio[n];
    if (k > 0)
      vmap[n].insert(Map::value_type(n, k));
  }
  // robimy operacje
  for (I m=0; m<M; ++m) {
    I from = ope[m].x;
    I to = ope[m].y;
    Map& mfrom = vmap[from];
    Map& mto = vmap[to];
    // najpierw reakcje
    for (I k=0; k<K; ++k) {
      I c = rea[k].x;
      I d = rea[k].y;

      Map::iterator it1 = mfrom.find(c);
      if (it1 != mfrom.end()) {
        Map::iterator it2 = mto.find(d);
        if (it2 != mto.end()) {
          // reakcja
          I comm = min(it1->second, it2->second);
          if (comm > 0) {
            osad += comm*2;
            it1->second -= comm;
            it2->second -= comm;
            if (it1->second == 0)
              mfrom.erase(it1);
            if (it2->second == 0)
              mto.erase(it2);
          }
        }
      }

      // w druga strone bo nie mamy w rea reversow
      it1 = mfrom.find(d);
      if (it1 != mfrom.end()) {
        Map::iterator it2 = mto.find(c);
        if (it2 != mto.end()) {
          // reakcja
          I comm = min(it1->second, it2->second);
          if (comm > 0) {
            osad += comm*2;
            it1->second -= comm;
            it2->second -= comm;
            if (it1->second == 0)
              mfrom.erase(it1);
            if (it2->second == 0)
              mto.erase(it2);
          }
        }
      }
    }
    // teraz mergowanie
    mto.insert(mfrom.begin(), mfrom.end());
    mfrom.clear();
  }
  return osad;
}

int main() {
  scanf("%d %d %d", &N, &M, &K);
  for (I n=1; n<=N; ++n) {
    scanf("%d", &fio[n]);
  }
  for (I m=0; m<M; ++m) {
    scanf("%d %d", &ope[m].x, &ope[m].y);
  }
  for (I k=0; k<K; ++k) {
    scanf("%d %d", &rea[k].x, &rea[k].y);
  }

  printf("%lld\n", brute());
  return 0;
}