hdu6200mustedge mustedge mustedge
来源:互联网 发布:数据库客户端如何使用 编辑:程序博客网 时间:2024/06/11 07:19
Give an connected undirected graph with n nodes and m edges, (n,m≤105) which has no selfloops or multiple edges initially.
Now we have q operations (q≤105):
⋅1 u v: add an undirected edge from u to v; (u≠v&&1≤u,v≤n)
⋅2 u v: count the number of mustedges from u to v; (1≤u,v≤n).
mustedge: we define set Ei as a path from u to v which contain edges in this path, and |∩k1Ei| is the number of mustedges. |x| means size of set x, and E1,E2…Ek means all the paths.
It’s guaranteed that ∑n,∑m,∑q≤106
Please note that maybe there are more than one edges between two nodes after we add edges. They are not the same, which means they can be in a set at the same time. Read the sample data for more information.
Input
Input starts with an integer T, denoting the number of test cases.
For each case:
First line are two number n and m;
Then next m lines, each contains two integers u and v, which indicates an undirected edge from u to v;
Next line contains a number q, the number of operations;
Then next q lines, contains three integers x, u and v where x
is the operation type, which describes an operation.
Output
For each test case, output “Case #x:” where x is the test case number starting from 1.
In each test case, print a single number one line when query the number of mustedges
.
Sample Input
24 31 22 33 452 1 41 2 32 1 42 2 32 2 48 91 22 31 33 44 54 65 75 87 852 7 82 1 62 4 71 6 82 5 6
Sample Output
Case #1:3201Case #2:0210
题意:有两种查询 第一种是将u,v两个点之间连一条边,另一种是查询u到v路径上的割边有几条。
题解:具体方法和我上篇博客差不多是从航线规划中抽出的模型。这个问题最直接的想法就是缩点然后生成一棵树,然后树剖维护路径。那么复杂度是qlognlogn,每次查询树剖一个log,线段树一个大常数log。这题首先卡你内存。。。我的AC代码C++可以,G++不行。然后卡你时间。。。应该是卡了树剖那个log。所以只能用另一个暴力合并的维护子树深度的方法。
=-=。做这题的时候深深感受到了没有大神给我看思路自己想自己码的绝望。。平时都觉得没事。。。码不出还能看题解。。这次有点绝望。。。在icpccamp看到了一波大佬的提示,然后就自己码了好久=-=回来回馈一下社会
听说还能用lct做 蒟蒻好久以前就准备学到现在还没看懂定义ORZ
#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<vector>using namespace std;//thanks to pyf ...//thanks to qhl ...const int N = 1e5 + 1;vector<pair<int,int> > edges;vector<int> G[N],g[N];bool is_cut[N*2];int dfn[N],low[N],L[N],R[N];int Index = 0,id = 0;int fa[N],f[N][21],dep[N];int n;void init(){ Index = 0, id = 0; memset(dfn,0,sizeof(dfn)); memset(is_cut,0,sizeof(is_cut)); for(int i = 0;i<N;i++) G[i].clear(),g[i].clear(),fa[i] = i; edges.clear();}void add_edge(int u,int v){ edges.push_back(make_pair(u,v)); G[u].push_back(edges.size() - 1); edges.push_back(make_pair(v,u)); G[v].push_back(edges.size() - 1);}void tarjan(int u,int Fa){ dfn[u] = low[u] = ++ Index; for(int i = 0;i != G[u].size();i ++) { int v = edges[G[u][i]].second; if(v == Fa) continue; if(!dfn[v]) { tarjan(v,u); low[u] = min(low[v],low[u]); if(low[v] > dfn[u]) is_cut[G[u][i]] = is_cut[G[u][i] ^ 1] = true; } else low[u] = min(low[u],dfn[v]); }}int find(int x){ if(x != fa[x]) fa[x] = find(fa[x]); return fa[x];}void merge(int u,int v){ u = find(u), v = find(v); if(u == v) return; if(dep[u] > dep[v]) swap(u,v); fa[v] = u;}void Create_Graph(){ for(int i = 1;i<=n;i++) tarjan(i,i); for(int i = 0;i<edges.size();i++) { int u = edges[i].first, v = edges[i].second; if(!is_cut[i]) merge(u,v); } for(int i = 0;i<edges.size();i++) { int u = edges[i].first, v = edges[i].second; if(is_cut[i]) g[find(u)].push_back(find(v)); } for(int i = 1;i<=n;i++) { sort(g[i].begin(),g[i].end()); g[i].erase(unique(g[i].begin(),g[i].end()),g[i].end()); }}void dfs(int u,int Fa,int d){ dep[u] = d,f[u][0] = Fa; for(int i = 1;i<=20;i++) f[u][i] = f[f[u][i-1]][i-1]; L[u] = ++ id; for(int i = 0;i != g[u].size();i ++) { int v = g[u][i]; if(v == Fa) continue; dfs(v,u,d+1); } R[u] = id;}int lca(int u,int v){ if(dep[u] < dep[v]) swap(u,v); for(int i = 20;i>=0;i--) if(dep[f[u][i]] >= dep[v]) u = f[u][i]; if(u == v) return u; for(int i = 20;i>=0;i--) if(f[u][i] != f[v][i]) u = f[u][i], v = f[v][i]; return f[u][0];}struct Tree{ int vis,sum;}t[N*4];void push_down(int l,int r,int step){ int mid = (l + r) / 2; if(!t[step].vis) return; t[step * 2].vis += t[step].vis; t[step * 2 + 1].vis += t[step].vis; t[step * 2].sum += t[step].vis * (mid - l + 1); t[step * 2 + 1].sum += t[step].vis * (r - (mid + 1) + 1); t[step].vis = 0;}void build(){ memset(t,0,sizeof(t));}void update(int l,int r,int ql,int qr,int val,int step){ if(l == ql && r == qr) { t[step].vis += val; t[step].sum += (r - l + 1) * val; return; } int mid = (l + r) / 2; push_down(l,r,step); if(qr <= mid) update(l,mid,ql,qr,val,step*2); else if(ql > mid) update(mid + 1,r, ql,qr,val,step*2+1); else update(l,mid,ql,mid,val,step * 2),update(mid+1,r,mid+1,qr,val,step*2+1);}int query(int x,int l,int r,int step){ if(l == r) return t[step].sum; int mid = (l + r) / 2; push_down(l,r,step); if(x <= mid) return query(x,l,mid,step*2); else return query(x,mid+1,r,step*2+1);}void link(int u,int v){ u = find(u), v = find(v); int anc = find(lca(u,v)); while(find(u) != find(anc)) { update(1,n,L[find(u)],R[find(u)],-1,1); merge(find(u),f[find(u)][0]); } while(find(v) != find(anc)) { update(1,n,L[find(v)],R[find(v)],-1,1); merge(find(v),f[find(v)][0]); }}int Get_Ans(int u,int v){ u = find(u), v = find(v); int anc = find(lca(u,v)); return query(L[u],1,n,1) + query(L[v],1,n,1) - 2 * query(L[anc],1,n,1);}int main(){ int T; scanf("%d", &T); int ka = 0; while(T--) { int m; init(); scanf("%d%d",&n,&m); for(int i = 0;i<m;i++) { int u,v; scanf("%d%d",&u,&v); add_edge(u,v); } Create_Graph(); build(); dfs(find(1),find(1),0); for(int i = 1;i<=n;i++) if(find(i) == i) update(1,n,L[i],L[i],dep[i],1); int q; scanf("%d",&q); printf("Case #%d:\n",++ka); for(int i = 0;i<q;i++) { int op,x,y; scanf("%d%d%d",&op,&x,&y); if(op == 1) link(x,y); else printf("%d\n",Get_Ans(x,y)); } }}
- hdu6200mustedge mustedge mustedge
- hdu6200 mustedge mustedge mustedge
- [HDU 6200] mustedge mustedge mustedge
- hdu 6200 mustedge mustedge mustedge
- Hdu-6200 mustedge mustedge mustedge(动态树+并查集)
- HDU 6200 mustedge mustedge mustedge [LCT+缩点]
- HDU6200 mustedge mustedge mustedge (2017 ACM/ICPC Asia Regional Shenyang Online)
- hdu2017沈阳网络赛补题(一)mustedge mustedge(数剖求lca+树状数组)
- HDU 6200 mustedge ACM/ICPC 2017 Shenyang Online(LCT动态缩点)
- <棋盘型DP> noip 2008 传纸条
- java线程模式
- Linux内核启动及文件系统加载过程
- dao-service-servlet-jsp构建简易web通讯录(三层开发)软件安装
- mysql table相关命令
- hdu6200mustedge mustedge mustedge
- 模型分类评价
- SpringBoot配置log4j2的JdbcAppender日志写入数据库,可定义哪些日志写入
- Docker for Windows 里的Shared Drives 设置不生效
- kuangbin J
- Java内部类详解
- 上拉电阻与下拉电阻
- 【复赛模拟试题】求和 分治+二分快速幂
- Linux中exec命令相关