这题写的好蛋疼,被一个bug卡了半天。。。这题主要就是要确定所有反应发生的顺序,因为一种反应只能发生一次。观察混合的过程,这其实可以看做是建一颗树,混合以后相当于建一个新结点,那么就可以用这个结点表示混合后的状态……那么,很容易发现,一个反应如果发生,那么就是在两个药水的lca处发生。接下来,相对顺序其实不重要,只要保证一个反应的子树中的反应都发生了就行了,因此,把所有的反应按其lca的深度排序,然后逐个计算就行了。刚开始虽然想到了会形成森林,但是tarjan求lca的时候没写好,导致lca会出现问题,调了半天,fuck……
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<stack>
#include<set>
#include<cmath>
#include<vector>
#include<bitset>
#define inf 0x3f3f3f3f
#define Inf 0x3FFFFFFFFFFFFFFFLL
#define eps 1e-6
#define pi acos(-1.0)
using namespace std;
typedef long long ll;
const int maxn = 500000 + 10;
vector<int>G[maxn];
vector<pair<int,int> >querys[maxn];
int pa[maxn],d[maxn],anc[maxn],w[maxn],tot;
pair<int,int>op[maxn],np[maxn];
int vis[maxn],flag[maxn],cnt;
int Find(int x)
{
return x == pa[x] ? x : pa[x] = Find(pa[x]);
}
void tarjan(int u)
{
pa[u] = u;
vis[u] = cnt;
for(int i = 0;i < (int)querys[u].size();++i)
{
int v = querys[u][i].first;
int x = querys[u][i].second;
if(vis[v] == cnt)
{
np[tot++] = make_pair(d[Find(v)],x);
}
}
for(int i = 0;i < (int)G[u].size();++i)
{
int v = G[u][i];
d[v] = d[u] - 1;
tarjan(v);
pa[v] = u;
}
}
int main()
{
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
memset(anc,0xff,sizeof(anc));
for(int i = 1; i <= n;++i)
scanf("%d",&w[i]);
for(int i = 1;i <= n + m;++i)
pa[i] = i;
int u,v;
int N = n;
for(int i = 1;i <= m;++i)
{
scanf("%d%d",&u,&v);
u = Find(u);
v = Find(v);
N++;
pa[u] = pa[v] = N;
G[N].push_back(v);
G[N].push_back(u);
flag[u] = flag[v] = true;
}
for(int i = 1;i <= k;++i)
{
scanf("%d%d",&u,&v);
op[i] = make_pair(u,v);
querys[u].push_back(make_pair(v,i));
querys[v].push_back(make_pair(u,i));
}
tot = cnt = 0;
for(int i = 1; i <= N;++i)
if(!flag[i])
{
cnt++;
tarjan(i);
}
sort(np,np + tot);
ll ans = 0;
for(int i = 0;i < tot;++i)
{
int x = np[i].second;
u = op[x].first;
v = op[x].second;
if(w[u] && w[v])
{
int y = min(w[u],w[v]);
ans += y*2LL;
w[u] -= y;
w[v] -= y;
}
}
cout<<ans<<endl;
return 0;
}