Bridges: The Final Battle
对修改操作按时间分治,设$solve(l,r,n,m)$为考虑时间在$[l,r]$的修改操作,作用范围是$n$个点,$m$条边的图。
若$l=r$,则暴力Tarjan统计桥边个数即可。
否则提取出$[l,r]$内涉及修改的所有边$E$,并将端点标记为$V$,显然$|V|=O(|E|)$。
加入$m$条边里除了$E$之外的所有边,显然无论怎么修改,这些边都会存在。
Tarjan求出边双连通分量,将边双缩点,可以得到一个森林,那么非树边永远都不可能成为桥,直接删除即可。
还可以注意到的是,还未加入的边的端点只可能在$V$中,因此可以求出$V$的虚树,不在虚树上的边永远都是桥,加入答案并删除即可。
而在虚树上的边,每条压缩边都表示一条链,需要额外记录这条树边表示几条桥边$w$,当以后这条树边成为桥边时,答案应该直接加上$w$。
经过以上几步处理之后,$n$和$m$均缩为$O(|V|)=O(|E|)=O(r-l)$。
取$mid=\lfloor\frac{l+r}{2}\rfloor$,递归$solve(l,mid,n',m')$,然后暴力处理所有$[l,mid]$的修改,再递归$solve(mid+1,r,n',m')$即可。
时间复杂度$T(n)=2T(\frac{n}{2})+O(n)=O(n\log n)$。
#include<cstdio>
#include<algorithm>
#include<map>
using namespace std;
typedef pair<int,int>P;
const int N=100010,M=100010,K=19;
int n,m,i,ans[M];
bool use[M],ex[M],cut[M],vis[N];
int g[N],v[M<<1],w[M<<1],nxt[M<<1],ed,f[N],dfn[N],low[N],num,from[N];
int G[N],V[N<<1],W[N<<1],NXT[N<<1],ED,id[N],sum[N],vip[N];
int O,ce,all,pos[M],q[K][M];
map<P,int>T;
struct E{
int x,y,w;
E(){}
E(int _x,int _y,int _w){x=_x,y=_y,w=_w;}
}e[K][M];
inline int ask(int x,int y){
if(x==y)return 0;
if(x>y)swap(x,y);
int&t=T[P(x,y)];
if(!t)e[0][t=++ce]=E(x,y,0);
return t;
}
inline void add(int x,int y,int z){v[++ed]=y;w[ed]=z;nxt[ed]=g[x];g[x]=ed;}
inline void ADD(int x,int y,int z){V[++ED]=y;W[ED]=z;NXT[ED]=G[x];G[x]=ED;}
void tarjan(int x){
dfn[x]=low[x]=++num;
for(int i=g[x];i;i=nxt[i])if(!dfn[v[i]]){
f[v[i]]=w[i],tarjan(v[i]);
if(low[x]>low[v[i]])low[x]=low[v[i]];
}else if(f[x]!=w[i]&&low[x]>dfn[v[i]])low[x]=dfn[v[i]];
if(f[x]&&low[x]==dfn[x])cut[f[x]]=1;
}
void dfs(int x,int y){
from[x]=y;
for(int i=g[x];i;i=nxt[i])if(!from[v[i]]&&!cut[w[i]])dfs(v[i],y);
}
inline void newedge(int x,int y,int w){all-=w;e[O][++ce]=E(x,y,w);}
void compress(int x,int y){
int d=0;
vis[x]=1;
for(int i=G[x];i;i=NXT[i]){
int u=V[i];
if(u==y)continue;
sum[u]=sum[x]+W[i];
compress(u,x);
if(!id[u])continue;
d++;
id[x]^=id[u];
}
if(d>1)vip[x]=1;
if(vip[x]){
for(int i=G[x];i;i=NXT[i]){
int u=V[i];
if(u==y)continue;
int t=id[u];
if(t)newedge(x,t,sum[t]-sum[x]);
}
id[x]=x;
}
}
void solve(int o,int l,int r,int n,int m,int pre){
O=o+1;
int i;
if(l==r){
for(i=1;i<=m;i++)cut[i]=0;
for(ed=0,i=1;i<=n;i++)g[i]=f[i]=dfn[i]=low[i]=from[i]=0;
num=0;
e[o][q[o][l]].w^=1;
for(i=1;i<=m;i++)if(e[o][i].w){
int x=e[o][i].x,y=e[o][i].y;
add(x,y,i),add(y,x,i);
}
for(i=1;i<=n;i++)if(!dfn[i])tarjan(i);
for(i=1;i<=m;i++)if(cut[i])pre+=e[o][i].w;
e[o][q[o][l]].w^=1;
ans[l]=pre;
return;
}
for(i=1;i<=m;i++)use[i]=cut[i]=pos[i]=0;
for(ed=0,i=1;i<=n;i++)g[i]=f[i]=dfn[i]=low[i]=from[i]=0;
num=0;
int cnt=0;
for(i=l;i<=r;i++)use[q[o][i]]=1;
for(i=1;i<=m;i++)if(!use[i]&&e[o][i].w){
int x=e[o][i].x,y=e[o][i].y;
add(x,y,i),add(y,x,i);
}
for(i=1;i<=n;i++)if(!dfn[i])tarjan(i);
for(i=1;i<=n;i++)if(!from[i])dfs(i,++cnt);
for(ED=0,i=1;i<=cnt;i++)vis[i]=vip[i]=G[i]=id[i]=sum[i]=0;
ce=all=0;
for(i=1;i<=m;i++)if(!use[i]&&e[o][i].w){
int x=e[o][i].x,y=e[o][i].y;
x=from[x],y=from[y];
if(x==y)continue;
ADD(x,y,e[o][i].w),ADD(y,x,e[o][i].w);
all+=e[o][i].w;
}
for(i=l;i<=r;i++){
int t=q[o][i];
if(!t)continue;
vip[from[e[o][t].x]]=vip[from[e[o][t].y]]=1;
}
for(i=1;i<=cnt;i++)if(vip[i]&&!vis[i])compress(i,0);
int mid=(l+r)>>1,_ce=ce,cv=0;
for(i=1;i<=cnt;i++)if(vip[i])vip[i]=++cv;
pre+=all;
for(i=1;i<=ce;i++)e[o+1][i].x=vip[e[o+1][i].x],e[o+1][i].y=vip[e[o+1][i].y];
for(i=1;i<=m;i++)if(use[i]){
int x=e[o][i].x,y=e[o][i].y;
e[o+1][++ce]=E(vip[from[x]],vip[from[y]],e[o][i].w);
pos[i]=ce;
}
for(i=l;i<=r;i++)q[o+1][i]=pos[q[o][i]];
solve(o+1,l,mid,cv,ce,pre);
ce=_ce;
for(i=1;i<=m;i++)use[i]=0;
for(i=l;i<=r;i++)use[q[o][i]]=1;
for(i=1;i<=m;i++)if(use[i])ex[i]=e[o][i].w;
for(i=l;i<=mid;i++)ex[q[o][i]]^=1;
for(i=1;i<=m;i++)if(use[i])e[o+1][++ce].w=ex[i];
solve(o+1,mid+1,r,cv,ce,pre);
}
int main(){
freopen("bridges3.in","r",stdin);freopen("bridges3.out","w",stdout);
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++){
char s[9];
int x,y;
scanf("%s%d%d",s,&x,&y);
q[0][i]=ask(x,y);
}
solve(0,1,m,n,ce,0);
for(i=1;i<=m;i++)printf("%d\n",ans[i]);
}
Bridges: The Final Battle的更多相关文章
- hdu 3986 Harry Potter and the Final Battle (最短路径)
Harry Potter and the Final Battle Time Limit: 5000/3000 MS (Java/Others) Memory Limit: 65536/6553 ...
- hdu3986Harry Potter and the Final Battle
给你一个无向图,然后找出当中的最短路, 除去最短路中的随意一条边,看最糟糕的情况下, 新的图中,第一个点到末点的最短路长度是多少. 我的做法是: 首先找出最短路,然后记录路径, 再一条一条边的删, 删 ...
- hdu 3986 Harry Potter and the Final Battle
一个水题WA了60发,数组没开大,这OJ也不提示RE,光提示WA...... 思路:先求出最短路,如果删除的边不是最短路上的,那么对结果没有影响,要有影响,只能删除最短路上的边.所以枚举一下最短路上的 ...
- [JZOJ6089]【CodeChef 2014 April Challenge】Final Battle of Chef【数据结构】【整体二分】
Description \(n,q,V\leq 100000,w_i\leq 10^9\) Solution 又是一道大数据结构 由于有一个下取整,这就导致了不同时间的修改值是不能简单的直接加在一起的 ...
- 【Dijstra堆优化】HDU 3986 Harry Potter and the Final Battle
http://acm.hdu.edu.cn/showproblem.php?pid=3986 [题意] 给定一个有重边的无向图,T=20,n<=1000,m<=5000 删去一条边,使得1 ...
- Final Battle #1 K题 Fire game
Description Fat brother and Maze are playing a kind of special (hentai) game on an N*M board (N rows ...
- 【转】最短路&差分约束题集
转自:http://blog.csdn.net/shahdza/article/details/7779273 最短路 [HDU] 1548 A strange lift基础最短路(或bfs)★254 ...
- 【转载】图论 500题——主要为hdu/poj/zoj
转自——http://blog.csdn.net/qwe20060514/article/details/8112550 =============================以下是最小生成树+并 ...
- 坑爹CF April Fools Day Contest题解
H - A + B Strikes Back A + B is often used as an example of the easiest problem possible to show som ...
随机推荐
- 阿里云使用js 实现OSS图片上传、获取OSS图片列表、获取图片外网访问地址(读写权限私有、读写权限公共);
详情请参考:https://help.aliyun.com/document_detail/32069.html?spm=a2c4g.11186623.6.763.ZgC59a 或者https://h ...
- Scrapy 框架 安装
Scrapy 框架 Scrapy是用纯Python实现一个为了爬取网站数据.提取结构性数据而编写的应用框架,用途非常广泛. 框架的力量,用户只需要定制开发几个模块就可以轻松的实现一个爬虫,用来抓取网页 ...
- asp.net core WebApi 快速入门
参考:https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/first-web-api?view=aspnetcore-2.1 官网的例子 直接 ...
- JCenter下载太慢, jcenter修改 https为http也许能帮助你
今天导入一个工程到studio,一直卡在下载那块. 看到下载地址是:https://jcenter.bintray.com/........https!!!! 到浏览器下载,果然也下载不下来.. 于是 ...
- 如何下载kubenetes最新的rpm包?
一,新增aliyun的软件仓库 tee /etc/yum.repos.d/kubernetes.repo <<-'EOF' [kubernetes] name=Kubernetes bas ...
- Ncurses - Panel
当你需要创建许多窗口时,你很快就会发现它们会变得难以管理.Panel library提供了很好的解决方案. Panel 实际上是一个窗口,通过容器 - 栈 来管理,栈顶的 panel 是完全可见的,其 ...
- Ubuntu安装搜狗sougou输入法
昨天ubuntu闪屏后进不去系统,之后重新安装的Ubuntu14.04,在软件中心安装了新立得软件包管理器 在网上下载搜狗输入法forlinux 网址:http://pinyin.sogou.com/ ...
- 今天才知道原来我还没弄清楚js中全局变量和局部变量的定义...
查资料看到这段还不错,来源:原文:https://blog.csdn.net/czh500/article/details/80429133 粘过来记录一下... 1.使用var声明变量,在方法内部是 ...
- BZOJ3172 [Tjoi2013]单词 字符串 SA ST表
原文链接http://www.cnblogs.com/zhouzhendong/p/9026543.html 题目传送门 - BZOJ3172 题意 输入$n(n\leq 200)$个字符串,保证长度 ...
- Vijos1982 NOIP2015Day2T2 子串 substring 动态规划
子串 (substring.cpp/c/pas) 题目链接 [问题描述]有两个仅包含小写英文字母的字符串 A 和 B.现在要从字符串 A 中取出 k 个 互不重叠 的非空子串,然后把这 k 个子串按照 ...