題意:給出一張n個點,m條邊的無向圖,有兩個操作:
1.刪除(u, v)間的一條邊
2.如果刪除(u, v)間的一條邊可使其不連通,找出這樣的邊的個數,就是找(u, v)間橋的個數
思路:首先離線這些操作,時光倒流從最終狀態逆著加邊加回原圖,可以考慮用並查集建樹,然後以樹作為最終狀態,再樹鏈剖分預處理下,建一顆線段樹維護區間和(葉子值為1代表當前邊為橋),如果有邊(u, v)要加入,那就將(u, v)這段區間的所對應的線段樹葉子值全清零,並設定標記陣列,因為已更新過的點不用再訪問
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
#pragma comment(linker, "/stack:102400000,102400000")
using
namespace
std;
typedef
long
long ll;
const
int maxn = 101000;
const
int inf = 0x3f3f3f3f;
struct edge
edge[maxn << 1];
int head[maxn], tot, val[maxn];
int top[maxn], fa[maxn], deep[maxn];
int num[maxn], p[maxn], fp[maxn];
int son[maxn], pos, mp[maxn];
void init()
void addedge(int u, int v)
void dfs1(int u, int pre, int d)
}}void getpos(int u, int sp)
}struct uf
int find(int x)
} uf;
map ma[maxn];
map ::iterator it;
int tr[maxn << 2], lazy[maxn << 2];
void pushup(int rt)
void build(int l, int r, int rt)
int mid = (l + r) >> 1;
build(lson);
build(rson);
pushup(rt);
}void update(int ql, int qr, int l, int r, int rt)
int mid = (l + r) >> 1;
if (ql <= mid)
update(ql, qr, lson);
if (qr > mid)
update(ql, qr, rson);
pushup(rt);
}int query(int ql, int qr, int l, int r, int rt)
void change(int u, int v)
update(p[fu], p[u], 1, pos, 1);
u = fa[fu], fu = top[u];
}if (deep[u] > deep[v]) swap(u, v);
if (u != v)
update(p[son[u]], p[v], 1, pos, 1);
}int answer(int u, int v)
res += query(p[fu], p[u], 1, pos, 1);
u = fa[fu], fu = top[u];
}if (deep[u] > deep[v]) swap(u, v);
if (u != v)
res += query(p[son[u]], p[v], 1, pos, 1);
return res;
}struct node
que[maxn];
int main()
for (int i = 1; i <= q; i++)
for (int i = 1; i <= n; i++)}}
}dfs1(1, 0, 0);
getpos(1, 1);
build(1, pos, 1);
// for (int i = 0; i < tot; i += 2)
// printf("%d %d\n", edge[i].from, edge[i].to);
// for (int i = 1; i <= n; i++)
// printf("%d\n", p[i]);
for (int i = 1; i <= n; i++)}}
for (int i = q; i >= 1; i--)
for (int i = 1; i <= q; i++)
if (que[i].op == 2)
printf("%d\n", que[i].ans);
}return
0;}
HDU 5458(樹鏈剖分)
題意 給乙個無向圖,兩種操作,刪除一條邊,詢問兩點之間關鍵路徑的數目。關鍵路徑,即刪除這條邊,兩點就不聯通了。保證圖一直聯通。解法 先在最後的圖上跑一顆生成樹。每有一條其他的邊,就對路徑上的所有邊 1。所以就存在兩種操作,對某一段 1,查詢某一段上0的個數,就可以用線段樹做了。pragma comm...
樹鏈剖分 模板
class match node a n struct no no aa n 4 void init void addpage int x,int y void dfs int s,int faa,int h 根節點,父節點和深度的 if max 0 son s sign void dfs2 int...
模板 樹鏈剖分
define maxn 50010 define l u u 1 define r u u 1 1 寫在類裡面爆棧 int n,m,q int tim 時間戳 int num maxn 樹上每個節點的初始值 int siz maxn siz u 表示以u為根的子樹的節點數 int top maxn ...