题解 | 算法竞赛进阶指南 BLO

BLO

https://ac.nowcoder.com/acm/contest/1060/A

思路

I.设在搜索树T中以x为根的树包含的点集为SubTree(x)。

II.这里去除割点可以理解为删除与该点相连的所有边。

III.这里提到的连通块是指当某一割点去除时:1.其中任何两个点都能相互到达 2.没有更大的连通块包含该块 当然,根据II,我们把单独的X也看做一个连通块

IV.为了方便,我们直接将(x,y)(满足x不能到y)成为“点对”

V. ~S:S的补集,A^B:在A中不包括点B的所有点构成的集合

利用Tarjan查找割点的同时,我们可以找出该割点X去除后剩余的连通块(有两种情况,一种是在SubTree(X)^X中,另一种是~SubTree(X))。

只要能够理解割点的求解过程,这还是很好理解的,这里不再赘述。

然后要求“点对”。

对于一个点X,不管是否为割点,点对(i,j)为“点对”,当且仅当

i != j且i、j属于两个不同的连通块

根据定义,很容易证明这个推论。

代码有多种写法,这里选取我能想到的最简单的写法。

在枚举连通块时,ans加上s[to[i]] * ( n - s[to[i]] ),即一次性处理一个连通块的所有点,它们与其他不属于这个连通块的点都构成“点对”。当然,别忘了X与~SubTree(X)。

代码

#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define MAXN 100005
#define MAXM 1000005

int n, m;
int hd[MAXN], nxt[MAXM], to[MAXM], tot;
int dfn[MAXN], low[MAXN], root, num;
LL ans[MAXN];
int s[MAXN];

void Add( int x, int y ){ nxt[++tot] = hd[x]; hd[x] = tot; to[tot] = y; }

void DFS( int x ){
    s[x] = 1;
    low[x] = dfn[x] = ++num;
    LL b(0);
    for ( int i = hd[x]; i; i = nxt[i] ){
        if ( !dfn[to[i]] ){
            DFS( to[i] ); s[x] += s[to[i]];
            low[x] = min( low[x], low[to[i]] );
            if ( dfn[x] <= low[to[i]] ) ans[x] += (long long)s[to[i]] * ( n - s[to[i]] ), b += s[to[i]];//发现新的连通块!
        } else low[x] = min( low[x], dfn[to[i]] );
    }
    ans[x] += (long long)( n - b - 1 ) * ( b + 1 ) + ( n - 1 );//算上~SubTree(X)与X
}

int main(){
    scanf( "%d%d", &n, &m );
    for ( int i = 1; i <= m; ++i ){
        int x, y; scanf( "%d%d", &x, &y ); Add( x, y ); Add( y, x );
    }
    DFS( 1 );
    for ( int i = 1; i <= n; ++i ) printf( "%lld\n", ans[i] );
    return 0;
}
全部评论

相关推荐

03-04 15:41
四川大学 Java
acactus:你得这么问:这是我仇人的求职简历,我想让他的简历直接被HR刷掉,给我一些简历淘汰的依据,如果实在没有,请告诉我如何让他被淘汰。
点赞 评论 收藏
分享
03-27 16:40
已编辑
门头沟学院 C++
26学院本太难了,很多公司机筛就给我刷了。机会都难拿到如果是简历存在问题也欢迎拷打————————————————————分割线——————————————————————2026.3.4更新:发完贴之后,时不时投递又收到了不少的笔试/面试邀请。主要是之前投递简历出去之后基本上都是沉默状态,年后好转了不少timeline:2026.01.21&nbsp;文远知行笔试,半年多没刷算法题&nbsp;-&gt;挂&nbsp;(后续HR说春招可以重新安排笔试)2026.2.4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;小鹏汇天&nbsp;技术一面,第二周收到结果&nbsp;-&gt;挂2026.2.12&nbsp;&nbsp;&nbsp;大众Cariad代招&nbsp;技术二面&nbsp;-&gt;Offer2026.2.28&nbsp;&nbsp;&nbsp;多益网络技术面试,由于风评太差,一直在犹豫要不要接面试&nbsp;-&gt;推迟-----------分割线-----------2026.3&nbsp;月前的某一天,临时去电网报名了二批计算机岗位的笔试2026.3.6&nbsp;从上家公司实习离职,氛围最好的一家公司,leader&nbsp;说可以帮忙转正,但是流程太长,而且我们部门据说只有一个&nbsp;hc,更想要研究生,我很有可能是会被签外包公司在这里干活,就离职了。2026.3.9&nbsp;入职新公司,大众Cariad&nbsp;以外部公司的身份进组,项目组签了三年,后续三年应该都可以在这里呆,不知道有没有希望原地跳槽。2026.3.10&nbsp;电网考试居然说我通过资格审查了,短信约我去参加资格审查,请假一天,买了&nbsp;12&nbsp;号晚上的机票回成都2026.3.15&nbsp;参加国家电网计算机类笔试2026.3.17&nbsp;电网出成绩了,感觉很低。觉得已经🈚️了2026.3.18&nbsp;收到电网面试通知,通知&nbsp;3.22-3.25&nbsp;这个时间去面试,我的岗位只招&nbsp;1&nbsp;个人。据说面试只有&nbsp;2-3&nbsp;人,不知道能不能成功----------分割线-----------2026.3.21&nbsp;电网面试结束,感觉回答的还勉勉强强,大概是2个岗位分别招1个人,一共11人面试,实际来了9人2026.3.27&nbsp;出面试成绩,满分100分,早上10:20左右发现面试成绩46,我震惊了,没截图,后面过了十分钟重新看发现面试成绩给我改成58了。但同样震惊。朋友问我是不是把面试官打了,哈哈
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

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