zoukankan      html  css  js  c++  java
  • POJ

    题意:给出一个无相图,然后q次新增加边,问在添加边的过程中桥的数目
    当且仅当无向边(u,v)为树枝的时候,需要满足dfn(u)<low(v),
    也就是v向上翻不到u及其以上的点,那么u-v之间一定能够有1条或者多条边不能删去,因为他们之间有一部分无环,是桥
    思路:首先我们知道在给定一张图之后,不断添加边,桥的数目只会减少而不是增加
    tarjan的使用就是缩点,将一个连通分量缩成一个点,那么那个连通分量中的边都不会是桥
    同时缩完点之后我们就会发现,桥其实就是新形成的树的边
    在添加的过程中,如果是在连通分量内就不会减少桥的数目
    如果是u,v在两个不同的连通分量中,那么u,v以及其lca(最小公共祖先)就会连成一个回路,就形成了一个新的连通分量
    那么被连接的这整个一段部分的所有桥的数目就会减少

    完整代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <vector>
    #include <stack>
    #define IOS ios::sync_with_stdio(0); cin.tie(0); using namespace std; typedef long long LL; typedef pair<int,int>pii; const double eps = 1e-8; const int inf = 0x3f3f3f3f; const int maxn = 1e5+10; const int max_edge = 4e5+5; struct Edge { int to, next; }edge[max_edge]; int top, head[maxn]; int pre[maxn]; int id, dfn[maxn], low[maxn]; int cnt; int bridge[maxn]; int n,m; void add(int u,int v){ edge[top].to = v; edge[top].next = head[u]; head[u] = top++; } void tarjan(int x,int f){ //更新时间戳 dfn[x] = low[x] = ++id; for(int i = head[x]; ~i;i = edge[i].next){ int v = edge[i].to; if(!dfn[v]){ tarjan(v,x); pre[v] = x; low[x] = min(low[v],low[x]); //桥的判定条件 if(low[v]>dfn[x]){ bridge[v] = 1; cnt++; } } else if(v != f){ low[x] = min(low[x],dfn[v]); } } } void init(){ memset(low,0,sizeof(low)); memset(dfn,0,sizeof(dfn)); memset(bridge,0,sizeof(bridge)); memset(head,-1,sizeof(head)); cnt = id = top = 0; } void lca(int u,int v){ //进入时交换一下,把根赋值给u if(dfn[u] < dfn[v]) swap(u,v); //先将底的一边走到同样的高度 while(dfn[u] > dfn[v]){ if(bridge[u]) cnt--,bridge[u]=0; u = pre[u]; } //两边同时向lca走 while(u != v){ if(bridge[u]) cnt--,bridge[u] = 0; if(bridge[v]) cnt--,bridge[v] = 0; u = pre[u]; v = pre[v]; } } int main(){
       //IOS (加速cin可以少一倍时间)
    int Case = 0; while(cin>>n>>m&&n&&m){ init(); for(int i =0;i<m;i++){ int u,v; cin>>u>>v; add(u,v),add(v,u); } tarjan(1,1); int q; cin>>q; cout<<"Case "<<++Case<<":"<<endl; while(q--){ int u,v; cin>>u>>v; lca(u,v); cout<<cnt<<endl; } } return 0; }
  • 相关阅读:
    python 获取文件大小,创建时间和访问时间
    url中的20%、22%、26%、7B%、%7D、28%、29% 代表真实的字符(转发)
    python3 采集需要登录的网页数据
    python3 模拟鼠标中轴滚动
    python3 爬虫小技巧,
    马拉松中级训练计划
    python 使用夜神模拟器
    Python3+mitmproxy安装使用教程(Windows)(转载)
    adb server version (31) doesn't match this client (41); killing...
    appium+python环境搭建
  • 原文地址:https://www.cnblogs.com/Tianwell/p/11328947.html
Copyright © 2011-2022 走看看