BZOJ3712 [PA2014]Fiolki
2017-03-29 10:52
295 查看
容易发现我们只需要求出每种反应的发生时间,然后排序做一遍即可
求反应的发生时间,就相当于一张图,开始每个点都是单独一个连通块,连通块会不断合并,求每条边的两个端点联通的时间
整体二分一下即可,每次判断现在是否联通吧边分到左右两边
用dfs版的话并查集回滚要按秩合并,多个log,所以写bfs版的就好
#include<iostream>
#include<cstring>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<iomanip>
#include<cstdlib>
#include<cstdio>
#include<map>
#include<bitset>
#include<set>
#include<stack>
#include<vector>
#include<queue>
using namespace std;
#define MAXN 500010
#define MAXM 200010
#define ll long long
#define eps 1e-8
#define MOD 1000000007
#define INF 1000000000
struct data{
int x;
int y;
int X;
int Y;
data(){
}
data(int _x,int _y,int _X=0,int _Y=0){
x=_x;
y=_y;
X=_X;
Y=_Y;
}
};
data q[MAXN];
int hd,tl;
data th[MAXN];
int n,m,H;
int a[MAXN];
data e[MAXN];
data h[MAXN];
int f[MAXN];
ll ans;
int fa(int x){
return f[x]==x?x:f[x]=fa(f[x]);
}
int main(){
int i;
scanf("%d%d%d",&n,&m,&H);
for(i=1;i<=n;i++){
scanf("%d",&a[i]);
}
for(i=1;i<=m;i++){
scanf("%d%d",&e[i].x,&e[i].y);
}
for(i=1;i<=H;i++){
scanf("%d%d",&h[i].x,&h[i].y);
h[i].Y=i;
}
q[(tl%=MAXN)++]=data(1,m,1,H);
int wzh=m+1;
while(hd!=tl){
data x=q[(hd%=MAXN)++];
int l=x.x,r=x.y,L=x.X,R=x.Y;
int mid=l+r>>1;
if(wzh>mid){
for(i=1;i<=n;i++){
f[i]=i;
}
wzh=1;
}
while(wzh<=mid){
f[fa(e[wzh].x)]=fa(e[wzh].y);
wzh++;
}
int tl=L-1,tr=R+1;
for(i=L;i<=R;i++){
if(fa(h[i].x)==fa(h[i].y)){
th[++tl]=h[i];
}
}
for(i=R;i>=L;i--){
if(fa(h[i].x)!=fa(h[i].y)){
th[--tr]=h[i];
}
}
memcpy(h+L,th+L,sizeof(data)*(R-L+1));
if(l!=r){
if(tl>=L){
q[(::tl%=MAXN)++]=data(l,mid,L,tl);
}
if(tl<R){
q[(::tl%=MAXN)++]=data(mid+1,r,tl+1,R);
}
}
}
for(i=1;i<=n;i++){
f[i]=i;
}
for(i=1;i<=m;i++){
f[fa(e[i].x)]=fa(e[i].y);
}
for(i=1;i<=H;i++){
if(fa(h[i].x)==fa(h[i].y)){
int t=min(a[h[i].x],a[h[i].y]);
ans+=t*2;
a[h[i].x]-=t;
a[h[i].y]-=t;
}
}
printf("%lld\n",ans);
return 0;
}
/*
4 3 2
27 46 75 69
4 2
3 2
2 1
1 3
3 4
*/
求反应的发生时间,就相当于一张图,开始每个点都是单独一个连通块,连通块会不断合并,求每条边的两个端点联通的时间
整体二分一下即可,每次判断现在是否联通吧边分到左右两边
用dfs版的话并查集回滚要按秩合并,多个log,所以写bfs版的就好
#include<iostream>
#include<cstring>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<iomanip>
#include<cstdlib>
#include<cstdio>
#include<map>
#include<bitset>
#include<set>
#include<stack>
#include<vector>
#include<queue>
using namespace std;
#define MAXN 500010
#define MAXM 200010
#define ll long long
#define eps 1e-8
#define MOD 1000000007
#define INF 1000000000
struct data{
int x;
int y;
int X;
int Y;
data(){
}
data(int _x,int _y,int _X=0,int _Y=0){
x=_x;
y=_y;
X=_X;
Y=_Y;
}
};
data q[MAXN];
int hd,tl;
data th[MAXN];
int n,m,H;
int a[MAXN];
data e[MAXN];
data h[MAXN];
int f[MAXN];
ll ans;
int fa(int x){
return f[x]==x?x:f[x]=fa(f[x]);
}
int main(){
int i;
scanf("%d%d%d",&n,&m,&H);
for(i=1;i<=n;i++){
scanf("%d",&a[i]);
}
for(i=1;i<=m;i++){
scanf("%d%d",&e[i].x,&e[i].y);
}
for(i=1;i<=H;i++){
scanf("%d%d",&h[i].x,&h[i].y);
h[i].Y=i;
}
q[(tl%=MAXN)++]=data(1,m,1,H);
int wzh=m+1;
while(hd!=tl){
data x=q[(hd%=MAXN)++];
int l=x.x,r=x.y,L=x.X,R=x.Y;
int mid=l+r>>1;
if(wzh>mid){
for(i=1;i<=n;i++){
f[i]=i;
}
wzh=1;
}
while(wzh<=mid){
f[fa(e[wzh].x)]=fa(e[wzh].y);
wzh++;
}
int tl=L-1,tr=R+1;
for(i=L;i<=R;i++){
if(fa(h[i].x)==fa(h[i].y)){
th[++tl]=h[i];
}
}
for(i=R;i>=L;i--){
if(fa(h[i].x)!=fa(h[i].y)){
th[--tr]=h[i];
}
}
memcpy(h+L,th+L,sizeof(data)*(R-L+1));
if(l!=r){
if(tl>=L){
q[(::tl%=MAXN)++]=data(l,mid,L,tl);
}
if(tl<R){
q[(::tl%=MAXN)++]=data(mid+1,r,tl+1,R);
}
}
}
for(i=1;i<=n;i++){
f[i]=i;
}
for(i=1;i<=m;i++){
f[fa(e[i].x)]=fa(e[i].y);
}
for(i=1;i<=H;i++){
if(fa(h[i].x)==fa(h[i].y)){
int t=min(a[h[i].x],a[h[i].y]);
ans+=t*2;
a[h[i].x]-=t;
a[h[i].y]-=t;
}
}
printf("%lld\n",ans);
return 0;
}
/*
4 3 2
27 46 75 69
4 2
3 2
2 1
1 3
3 4
*/
相关文章推荐
- 【bzoj3712】[PA2014]Fiolki
- 【PA2014】【BZOJ3712】Fiolki
- BZOJ 3712: [PA2014]Fiolki
- BZOJ 3712: [PA2014]Fiolki 倍增+想法
- bzoj3712 [PA2014]Fiolki
- bzoj 3712: [PA2014]Fiolki
- 【BZOJ】3712: [PA2014]Fiolki
- BZOJ 3712: [PA2014]Fiolki 思路题
- bzoj 3712: [PA2014]Fiolki
- [bzoj3712][PA2014]Fiolki_倍增LCA
- bzoj 3712 [PA2014]Fiolki(LCA)
- BZOJ3712 PA2014Fiolki(kruskal重构树)
- BZOJ:3712: [PA2014]Fiolki
- bzoj 3712: [PA2014]Fiolki
- 3712: [PA2014]Fiolki(思路好题)
- 3712: [PA2014]Fiolki
- 3712: [PA2014]Fiolki LCA 思路题
- 【bzoj3714】【PA2014】【Kuglarz】【最小生成树】
- 【PA2014】【BZOJ3717】Pakowanie
- bzoj 3715: [PA2014]Lustra 乱搞