HDU 5458 Stability
Stability
This problem will be judged on HDU. Original ID: 5458
64-bit integer IO format: %I64d Java class name: Main
Given an undirected connected graph G with n nodes and m edges, with possibly repeated edges and/or loops. The stability of connectedness between node u and node v is defined by the number of edges in this graph which determines the connectedness between them (once we delete this edge, node u and v would be disconnected).
You need to maintain the graph G, support the deletions of edges (though we guarantee the graph would always be connected), and answer the query of stability for two given nodes.
Input
There are multiple test cases(no more than 3 cases), and the first line contains an integer t, meaning the totally number of test cases.
For each test case, the first line contains three integers n, m and q, where 1≤n≤3×104,1≤m≤105 and 1≤q≤105. The nodes in graph G are labelled from 1 to n.
Each of the following m lines contains two integers u and v describing an undirected edge between node u and node v.
Following q lines - each line describes an operation or a query in the formats:
⋅ 1 a b: delete one edge between a and b. We guarantee the existence of such edge.
⋅ 2 a b: query the stability between a and b.
Output
For each test case, you should print first the identifier of the test case.
Then for each query, print one line containing the stability between corresponding pair of nodes.
Sample Input
1
10 12 14
1 2
1 3
2 4
2 5
3 6
4 7
4 8
5 8
6 10
7 9
8 9
8 10
2 7 9
2 7 10
2 10 6
2 10 5
1 10 6
2 10 1
2 10 6
2 3 10
1 8 5
2 5 10
2 4 5
1 7 9
2 7 9
2 10 5
Sample Output
Case #1:
0
0
0
0
2
4
3
3
2
3
4
Source
2015 ACM/ICPC Asia Regional Shenyang Online
解题:树链剖分
逆向操作,把删边视为加边,除去删除的那些边,玩树链剖分,首先,你得有棵树,没树,什么都是扯淡。
我们把要删的那些边从图上统统删除,剩下的残图不一定就是树,所以用并查集在残图上找棵树,树的边权都设为1,然后把残图中不在树上的边都加到树上,这样形成环了,那么把环上的树边全部置0.
现在开始删边(实际是加边,因为逆序操作)和查询,是的,逆序的,每次加边,就把形成的环,环上的树边都置成0,查询就查询这条路径上的边权和即可
#include <iostream>
#include <stdio.h>
#include <set>
#include <algorithm>
#include <cstring>
using namespace std;
typedef pair<int,int> PII;
const int maxn = ;
struct arc {
int to,next;
arc(int x = ,int y = -) {
to = x;
next = y;
}
} e[maxn<<];
struct node {
int lt,rt,sum,lazy;
} tree[maxn<<];
int head[maxn],tot;
void add(int u,int v) {
e[tot] = arc(v,head[u]);
head[u] = tot++;
}
inline void pushup(int v) {
tree[v].sum = tree[v<<].sum + tree[v<<|].sum;
}
inline void pushdown(int v) {
if(~tree[v].lazy) {
tree[v<<].sum = (tree[v<<].rt - tree[v<<].lt + )*tree[v].lazy;
tree[v<<].lazy = tree[v].lazy;
tree[v<<|].sum = (tree[v<<|].rt - tree[v<<|].lt + )*tree[v].lazy;
tree[v<<|].lazy = tree[v].lazy;
tree[v].lazy = -;
}
}
void build(int lt,int rt,int v) {
tree[v].lt = lt;
tree[v].rt = rt;
tree[v].lazy = -;
if(lt == rt) {
tree[v].sum = ;
return;
}
int mid = (lt + rt)>>;
build(lt,mid,v<<);
build(mid + ,rt,v<<|);
pushup(v);
}
void update(int lt,int rt,int val,int v) {
if(lt <= tree[v].lt && rt >= tree[v].rt) {
tree[v].sum = (tree[v].rt - tree[v].lt + )*val;
tree[v].lazy = val;
return;
}
pushdown(v);
if(lt <= tree[v<<].rt) update(lt,rt,val,v<<);
if(rt >= tree[v<<|].lt) update(lt,rt,val,v<<|);
pushup(v);
}
int query(int lt,int rt,int v) {
if(lt == tree[v].lt && rt == tree[v].rt) return tree[v].sum;
pushdown(v);
int mid = (tree[v].lt + tree[v].rt)>>;
if(rt <= mid) return query(lt,rt,v<<);
if(lt > mid) return query(lt,rt,v<<|);
return query(lt,mid,v<<) + query(mid + ,rt,v<<|);
}
int fa[maxn],dep[maxn],top[maxn],siz[maxn],son[maxn],loc[maxn],cnt;
void FindHeavyEdge(int u,int father,int depth) {
fa[u] = father;
dep[u] = depth;
siz[u] = ;
son[u] = -;
for(int i = head[u]; ~i; i = e[i].next) {
if(e[i].to == father) continue;
FindHeavyEdge(e[i].to,u,depth + );
siz[u] += siz[e[i].to];
if(son[u] == - || siz[son[u]] < siz[e[i].to])
son[u] = e[i].to;
}
}
void ConnectHeavyEdge(int u,int ancestor) {
top[u] = ancestor;
loc[u] = ++cnt;
if(son[u] != -) ConnectHeavyEdge(son[u],ancestor);
for(int i = head[u]; ~i; i = e[i].next) {
if(e[i].to == fa[u] || e[i].to == son[u]) continue;
ConnectHeavyEdge(e[i].to,e[i].to);
}
}
void UPDATE(int u,int v,int val = ) {
while(top[u] != top[v]) {
if(dep[top[u]] < dep[top[v]]) swap(u,v);
update(loc[top[u]],loc[u],val,);
u = fa[top[u]];
}
if(u == v) return;
if(dep[u] > dep[v]) swap(u,v);
update(loc[son[u]],loc[v],val,);
}
int QUERY(int u,int v,int ret = ) {
while(top[u] != top[v]) {
if(dep[top[u]] < dep[top[v]]) swap(u,v);
ret += query(loc[top[u]],loc[u],);
u = fa[top[u]];
}
if(u == v) return ret;
if(dep[u] > dep[v]) swap(u,v);
return ret + query(loc[son[u]],loc[v],);
}
int u,v,ans[maxn],uf[maxn],op[maxn],x[maxn],y[maxn];
bool used[maxn];
int Find(int x) {
if(x != uf[x]) uf[x] = Find(uf[x]);
return uf[x];
}
multiset<PII>S,V;
int main() {
int kase,n,m,q,cs = ;
scanf("%d",&kase);
while(kase--) {
S.clear();
V.clear();
scanf("%d%d%d",&n,&m,&q);
for(int i = tot = cnt = ; i < m; ++i) {
scanf("%d%d",&u,&v);
if(u > v) swap(u,v);
S.insert(PII(u,v));
}
for(int i = ; i <= n; ++i) {
head[i] = -;
used[i] = false;
uf[i] = i;
}
for(int i = ; i < q; ++i) {
scanf("%d%d%d",op + i,x + i,y + i);
if(x[i] > y[i]) swap(x[i],y[i]);
if(op[i] == ) S.erase(S.find(PII(x[i],y[i])));
}
for(auto &it:S) {
int a = Find(it.first),b = Find(it.second);
if(a != b) {
V.insert(it);
add(it.first,it.second);
add(it.second,it.first);
uf[a] = b;
}
}
FindHeavyEdge(,,);
ConnectHeavyEdge(,);
build(,cnt,);
for(auto &it:S)
if(V.find(it) == V.end()) UPDATE(it.first,it.second);
for(int i = q-; i >= ; --i)
if(op[i] == ) UPDATE(x[i],y[i]);
else if(op[i] == ) ans[i] = QUERY(x[i],y[i]);
printf("Case #%d:\n",cs++);
for(int i = ; i < q; ++i)
if(op[i] == ) printf("%d\n",ans[i]);
}
return ;
}
HDU 5458 Stability的更多相关文章
- hdu 5458 Stability(树链剖分+并查集)
Stability Time Limit: 3000/2000 MS (Java/Others) Memory Limit: 65535/102400 K (Java/Others)Total ...
- Hdu 5458 Stability (LCA + 并查集 + 树状数组 + 缩点)
题目链接: Hdu 5458 Stability 题目描述: 给出一个还有环和重边的图G,对图G有两种操作: 1 u v, 删除u与v之间的一天边 (保证这个边一定存在) 2 u v, 查询u到v的路 ...
- HDU 5458 Stability(双连通分量+LCA+并查集+树状数组)(2015 ACM/ICPC Asia Regional Shenyang Online)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5458 Problem Description Given an undirected connecte ...
- HDU 5458 Stability (树链剖分+并查集+set)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5458 给你n个点,m条边,q个操作,操作1是删边,操作2是问u到v之间的割边有多少条. 这题要倒着做才 ...
- 并查集+树链剖分+线段树 HDOJ 5458 Stability(稳定性)
题目链接 题意: 有n个点m条边的无向图,有环还有重边,a到b的稳定性的定义是有多少条边,单独删去会使a和b不连通.有两种操作: 1. 删去a到b的一条边 2. 询问a到b的稳定性 思路: 首先删边考 ...
- HDU 4569 Special equations(取模)
Special equations Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u S ...
- HDOJ 2111. Saving HDU 贪心 结构体排序
Saving HDU Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- 【HDU 3037】Saving Beans Lucas定理模板
http://acm.hdu.edu.cn/showproblem.php?pid=3037 Lucas定理模板. 现在才写,noip滚粗前兆QAQ #include<cstdio> #i ...
- hdu 4859 海岸线 Bestcoder Round 1
http://acm.hdu.edu.cn/showproblem.php?pid=4859 题目大意: 在一个矩形周围都是海,这个矩形中有陆地,深海和浅海.浅海是可以填成陆地的. 求最多有多少条方格 ...
随机推荐
- 转 php中$_request与$_post、$_get的区别
php中有$_REQUEST与$_POST.$_GET用于接受表单数据,当时他们有何种区别,什么时候用那种最好. 一.$_REQUEST与$_POST.$_GET的区别和特点 $_REQUEST[]具 ...
- 216 Combination Sum III 组合总和 III
找出所有可能的 k 个数,使其相加之和为 n,只允许使用数字1-9,并且每一种组合中的数字是唯一的.示例 1:输入: k = 3, n = 7输出:[[1,2,4]]示例 2:输入: k = 3, n ...
- Java_JDBC连接数据库_使用读取配置文件的方式
package com.homewoek3_4.dao; import java.io.IOException; import java.io.InputStream; import java.sql ...
- Java_JDBC连接数据库
package com.accp.dao; import java.sql.Connection; import java.sql.DriverManager; import java.sql.Pre ...
- listBox 搜索左右移动
<td align="left" width="50%"> 查询:<asp:TextBox ID="SacffSearch" ...
- 修改xampp的mysql默认密码和端口
修改MySQL默认密码 MySQL 的“root”用户默认状态是没有密码的,所以在 PHP 中您可以使用 mysql_connect("localhost","root& ...
- struts2 使用json
前台代码: Struts.xml: UserAction: 注意: 1)struts类库里面没有提供ezmorph-1.0.6.jar文件,所以要手动添加:
- convertquota - 把老的配额文件转换为新的格式
总览 (SYNOPSIS) convertquota [ -ug ] filesystem 描述 (DESCRIPTION) convertquota 把老的配额文件 quota.user 和 quo ...
- bind - 将一个名字和一个套接字绑定到一起
SYNOPSIS 概述 #include <sys/types.h> #include <sys/socket.h> int bind(int sockfd, struct s ...
- vs code 用户代码片段 html.json
{ // Place your snippets for html here. Each snippet is defined under a snippet name and has a p ...