首页 > 其他分享 >BOZJ 1123: [POI2008]BLO tarjan求割点

BOZJ 1123: [POI2008]BLO tarjan求割点

时间:2023-07-07 13:36:51浏览次数:42  
标签:tarjan ch POI2008 求割点 int dfn low include size



1123: [POI2008]BLO


Time Limit: 10 Sec  Memory Limit: 162 MB

Submit: 1140  Solved: 505

[Submit][Status][Discuss]

Description


Byteotia城市有n个 towns m条双向roads. 每条 road 连接 两个不同的 towns ,没有重复的road. 所有towns连通。


Input


输入n<=100000 m<=500000及m条边


Output


输出n个数,代表如果把第i个点去掉,将有多少对点不能互通。


Sample Input


5 5
1 2
2 3
1 3
3 4
4 5


Sample Output


8
8
16
14
8




点对是有序的、去掉的点也要算

对于一个去掉的点,要产生除了包括其本身在内的点对,那该点一定是割点

所以就求割点啊,每个连通块一顿乘就好啦


先随手放一个求割点

void tarjan(int u)
{
	dfn[u]=low[u]=++cnt;size[u]=1;
	int tmp=0;
	for(int i=last[u];i;i=e[i].nt)
	{
		if(e[i].to==fa[u])continue;
		if(!dfn[e[i].to])
		{
			son[u]++;fa[e[i].to]=u;tarjan(e[i].to);size[u]+=size[e[i].to];
			//在外面加son的绝壁只有我这样的傻叉 
			low[u]=min(low[u],low[e[i].to]);
			if(low[e[i].to]>=dfn[u])
			iscut[u]=1;
		}
		else if(dfn[e[i].to]<low[u])
		low[u]=dfn[e[i].to];
	}
	if(fa[u]==0&&son[u]<=1)iscut[u]=0; 
}


没有调好虚。。。




代码:

#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<complex>
#include<iostream>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<string>
#include<queue>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
	return x*f;
}
const int N=100100;
int n,m,ecnt,last[N],dfn[N],low[N],size[N],son[N],fa[N],cnt;
bool iscut[N];
ll ans[N];
struct EDGE{int to,nt;}e[N<<4];
inline void add(int u,int v)
{e[++ecnt]=(EDGE){v,last[u]};last[u]=ecnt;}
void tarjan(int u)
{
	dfn[u]=low[u]=++cnt;size[u]=1;
	int tmp=0;
	for(int i=last[u];i;i=e[i].nt)
	{
		if(e[i].to==fa[u])continue;
		if(!dfn[e[i].to])
		{
			fa[e[i].to]=u;tarjan(e[i].to);size[u]+=size[e[i].to];
			low[u]=min(low[u],low[e[i].to]);
			if(low[e[i].to]>=dfn[u])
			{
				ans[u]+=tmp*size[e[i].to];
				tmp+=size[e[i].to];
			}
		}
		else if(dfn[e[i].to]<low[u])
		low[u]=dfn[e[i].to];
	}
	ans[u]+=ll(n-1-tmp)*tmp;
}
int main()
{
	n=read();m=read();
	for(int i=1;i<=m;i++)
	{int u=read(),v=read();add(u,v);add(v,u);}
	tarjan(1);
	for(int i=1;i<=n;i++)
	printf("%lld\n",(ans[i]+n-1)<<1);;
	return 0;
}
/*
5 5
1 2
2 3
1 3
3 4
4 5

8
8
16
14
8
*/




标签:tarjan,ch,POI2008,求割点,int,dfn,low,include,size
From: https://blog.51cto.com/u_16181403/6651997

相关文章

  • [算法学习笔记] Tarjan LCA
    在讲解之前,我们先来看一道模板题:LuoguP3379最近公共祖先(LCA)WhatisLCALCA,即最近公共祖先。什么意思呢,我们举个例子:将就着看吧qwq这棵树中,0为根节点。若规定\(LCA(x,y)\)为\(x,y\)的最近公共祖先,则\(LCA(5,6)=2;LCA(4,3)=1;LCA(5,3)=0\)。还有很多,这里不一一列举了。最......
  • 无向图Tarjan浅谈
    NoteTarjanPart1怎么做自己看书Part2为什么是对的证明:搜索树是一棵树由于每个节点都只会访问一次,回溯一次,故会访问(n-1)*2条边,只取访问时的边,即n-1条,可以构成树证毕。证明:在一个简单环上的一条边不可能是桥如果破除这条边,只能把环断成链,不会损坏连通性。证毕。证明......
  • POJ2117 Electricity 题解 tarjan点双连通分量 割点
    题目链接:http://poj.org/problem?id=2117题目大意:给定一个由\(n\)个点\(m\)解题思路:tarjan,判断\(u\)的子节点有几个\(v\)满足\(low[v]\gedfn[u]\)就是答案,但是同时如果\(u\)不是这个dfs树的根节点,个数还要加\(1\)。示例程序1(C++11,POJ不支持):#include<bits/stdc++.h>......
  • P2860 [USACO06JAN]Redundant Paths G 题解 tarjan边双连通分量
    题目链接:https://www.luogu.com.cn/problem/P2860题目大意:给定一个无向连通图,求至少加几条边,能使其变成一个边双连通图。解题思路:边双连通分量缩点后计算度数为\(1\)的节点个数,假设有\(cnt\)个,则答案为\((cnt+1)/2\)。示例程序:#include<bits/stdc++.h>usingnamespacestd;......
  • CF402E Strictly Positive Matrix 题解 tarjan强连通分量
    题目链接:http://codeforces.com/problemset/problem/402/E题目大意:给出一个矩阵\(A\),问是否存在一个正整数\(k\)使得\(A^k\)解题思路:根据矩阵的性质,\(A^k_{i,j}\gt0\)当且仅当\(i\)到\(j\)所以可以把矩阵转成图论模型,若\(A_{i,j}\gt0\),则从\(i\)往\(j\)如果所有点......
  • POJ2117 Electricity 题解 tarjan点双连通分量 割点
    题目链接:http://poj.org/problem?id=2117题目大意:给定一个由\(n\)个点\(m\)条边构成的无向图,请你求出该图删除一个点之后,连通块最多有多少。解题思路:tarjan,判断\(u\)的子节点有几个\(v\)满足\(low[v]\gedfn[u]\)就是答案,但是同时如果\(u\)不是这个dfs树的根节......
  • Tarjan算法
    Tarjan算法1算法简介还记得无向图判连通块吗?对于无向图中,判连通块是一件很容易的事。你只需要dfs(深度优先搜索)一下就可以了。但是,如果我们把无向图换成有向图呢?这就是另一个故事了......2算法定义RobertTarjan计算机科学家,以LCA,Tarjan等算法闻名。Tarjan是求强连......
  • Tarjan
    定义强连通分量:图中极大的任意两个结点连通的子图。点双连通分量:对于一个无向图,假如仅仅对于该图而言其中不包含割点,那么称这个图是点双连通的。对于一个无向图中的极大点双连通的子图,我们称这个子图为点双连通分量。边双连通分量:假如删去这条边后图不连通,那么称这条边为割边。......
  • tarjan算法
    求强连通分量:#include<bits/stdc++.h>usingnamespacestd;intmain(){intn,m;scanf("%d%d",&n,&m);vector<vector<int>>adj(n+1);for(inti=0;i<m;i++){intu,v;scanf("%d%d",&......
  • Codeforces Round 244 (Div. 2) C. Checkposts(tarjan)
    题目链接思路考虑到如果一些点两两都能互相到达,那么这些点中,只要有一个点是安全的,就可以顾及到其他所有点,而这些点就是强连通分量(SCC)。思路很简单,就是每一个强连通分量中的最小值相加得到第一问的解,而第二问就是求每一个强连通分量有几个最小值,相乘得到答案。代码#include<i......