割点和桥模板

寻找连通图的割点和桥用的也是tarjan算法,我们计算每个点不经过父亲能到达点的最小dfs序,如果是大于等于父亲的,则说明去掉父节点,该点即无法同上面连通,所以父节点是割点。桥类似,我们对于每个点标记它到父亲的那条边是否是桥。

cf1277E:

给出一个图求对于两点ab,有多少对xy使得从x到y的每一条路径都必经ab。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include<bits/stdc++.h>
using namespace std;

const int maxn=2e5+1;
const int maxm=5e5+1;
#define ll long long
#define fo(i,n) for(int i=0;i<=n;i++)
struct edge{
    int to,next;
}es[maxm*2];
int head[maxn];
int cnt;
void add(int u,int v){
    es[++cnt]=(edge){v,head[u]};
    head[u]=cnt;
}
int dfn[maxn],low[maxn];    //low是表示不通过父节点能回到的最小节点
int ind;
int cut[maxn];

void tarjan(int x,int fa){
    dfn[x]=low[x]=++ind;
    int child=0;
    for(int i=head[x];i;i=es[i].next){
        int v=es[i].to;
        if(!dfn[v]){
            child++;
            tarjan(v,x);
            low[x]=min(low[x],low[v]);
            if(!cut[x]){
                if(fa!=x&&low[v]>=dfn[x]){  //子节点不能到达比父亲小的节点,
                    //相等表示另有一条路能回到父节点,如果是桥,要去掉等号
                    cut[x]=1;
                }
            }
        }else if(v!=fa){    //遇到已经到达过的且不是父亲,说明可以绕道回去
            low[x]=min(low[x],dfn[v]);
        }
    }
    if(fa==x&&child>1&&!cut[x]){    //根节点判断方法不一样
        cut[x]=1;
    }
}
int flag[maxn];
bool vis[maxn];
void dfs(int x,int f,int stop){
    flag[x]+=f;vis[x]=1;
    for(int i=head[x],v;i;i=es[i].next){
        v=es[i].to;
        if(!vis[v]&&v!=stop)
            dfs(v,f,stop);
    }
}

int t,n,m;
int main(){
    cin>>t;
    while(t--){
        int a,b;
        cin>>n>>m>>a>>b;
        for(int i=1;i<=n;i++){
            dfn[i]=0;
            low[i]=0;
            cut[i]=0;
            head[i]=0;
        }
        for(int i=0,x,y;i<m;i++){
            cin>>x>>y;
            add(x,y);
            add(y,x);
        }
        for(int i=1;i<=n;i++){
            if(!dfn[i]){
                cnt=0;
                tarjan(i,i);
            }
        }
        ll res=0;
        if(cut[a]&&cut[b]){
            fo(i,n) flag[i]=0;
            fo(i,n) vis[i]=0;
            dfs(a,1,b);
            fo(i,n) vis[i]=0;
            dfs(b,2,a);
            int anum=0,bnum=0;
            for(int i=1;i<=n;i++){
                if(flag[i]==1)
                    anum++;
                if(flag[i]==2)
                    bnum++;
            }
            res=((ll)anum-1)*(bnum-1);
        }
        cout<<res<<endl;
    }
    return 0;
}

桥的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int low[MAXN], dfn[MAXN], iscut[MAXN], dfs_clock;
bool isbridge[MAXN];
vector<int> G[MAXN];
int cnt_bridge;
int father[MAXN];

void tarjan(int u, int fa) {
  father[u] = fa;
  low[u] = dfn[u] = ++dfs_clock;
  for (int i = 0; i < G[u].size(); i++) {
    int v = G[u][i];
    if (!dfn[v]) {
      tarjan(v, u);
      low[u] = min(low[u], low[v]);
      if (low[v] > dfn[u]) {
        isbridge[v] = true;
        ++cnt_bridge;
      }
    } else if (dfn[v] < dfn[u] && v != fa) {
      low[u] = min(low[u], dfn[v]);
    }
  }
}
全部评论

相关推荐

04-12 21:52
南开大学 Java
鼠鼠有点摆,去年边学着没敢投简历,没实习。从1月到现在总共面了五次,四次字节的日常(HR打电话约面试才敢去的),然后一次腾讯的暑期,都是一面挂,其他则是没给面。暑期的岗,4.2才开始海投,前面想着等字节第四次一面后再投,结果挂,而且感觉投晚了。字节投了11个,9个简历挂,剩下2个没动静。阿里全都简历挂,剩下的在&quot;投递简历&quot;。腾讯给了一次面。然后其他大中厂、手机厂什么的都是做完测评or笔试就没下文,打开几个看也是终止流程,感觉剩下的也应该是简历挂了。感觉是简历的原因?项目部分,几次面试,感觉面试官主要就拷问过秒杀这一个点。自己说的时候会尝试把sse那条说成亮点,但除了腾讯面试官问过一下这整个点在业务方面对用户有什么用之类的问题外,其他最多只是问一下sse八股...感觉也许不是很让面试官感兴趣。这个短链接也是无人问津,就被问过一回雪花算法的设计。也许我该拿点评改改,然后再在网上找一个什么项目,凑两个,而不是用自己现在这两个项目?或者是点评改改放前面,然后原本第一个项目,把秒杀抽掉,剩下的想办法从网上火的RAG项目里移植点亮点,或者直接就用网上的RAG项目?感觉我主要还是偏向后端开发,但是感觉如果除开点评,再拿一个项目,想不到有什么自己能掌控且跟点评不重的。然后鼠鼠之前主要的问题是担心面试让打开项目演示,然后就一直花时间在用AI整第一个项目,第二个项目都没时间整,第四次面试之前还因为太害怕被认为不熟悉项目,跟AI一起把简历的说辞做了大幅度弱化,然后暑期都是拿弱化后的简历投的,感觉是不是看上去太没有吸引力就直接给简历挂了。(图1是弱化后的,图2是弱化前的,但之前3月初投了几家好像也是简历挂。)而且因为3月花了很多时间整在跟AI整代码,导致八股和算法都没怎么看,算法之前有跟灵神题单刷一些,还算入门,但是八股只看了一些基本的,可能面试的时候只答得上来60-70%,而且表述有些混乱,都是想到哪说到哪;前面几回面试基本上都有大板块的基础八股没答出来,比如RedisZ&nbsp;Set数据结构,MQ延时消息、可靠性保证,JVM内存分配的过程、GC&nbsp;roots,JUC锁,设计模式。现在有点不知道该怎么办。求大佬们给点简历修改建议或者面试准备建议,不胜感激!
何时能不做牛马:简历每个点之间的间距可以缩一下。几乎没遇到过要演示项目的情况,即使万一遇上了你也可以说部署在其他电脑上本地没代码。nku不应该简历挂吧?抓紧背背八股练练表达,不要放弃,五六月份找到也不晚(不然还得提前入职
应届生简历当中,HR最关...
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务