[POI2008]BLO-Blockade,洛谷之提高历练地,强连通分量

正题

      [POI2008]BLO-Blockade

      这一题很神奇啊~

      我们来想想两个点不能连通和强连通有什么关系。

      那么其实很明显,如果当前点所遍历到的子节点不能遍历到祖先节点,那么说明子节点只能通过该点来去到祖先节点,这样产生的有序点对数量就是son[x]*(n-son[x]-1)*2,(假设当前点为x,则儿子节点即为son[x])

      所以可以延伸出来一个概念——割点,割点即为去掉该点后,原图被分为更多的连通块。

      所以我们判断该儿子是否只能通过该点到达祖先节点,是的话那就要加上答案,否则就不用理。

      具体看下代码,不懂怎么判割点的建议去学一学

#include
#include
#include
#include
#include
using namespace std;

int m;
long long n;
struct edge{
	int y,next,x;
}s[1000010];
struct node{
	int dfn,low;
}op[100010];
long long ans[100010];
int first[100010];
long long size[100010];
int len=0;
int now=0;

void ins(int x,int y){
	len++;
	s[len].y=y;s[len].next=first[x];first[x]=len;
}

void Tarjan(int x){
	op[x].low=op[x].dfn=++now;
	size[x]=1;
	long long t=0;
	for(int i=first[x];i!=0;i=s[i].next){
		int y=s[i].y;
		if(op[y].dfn==0){//如果y没有被遍历过
			Tarjan(y);//往下搜
			size[x]+=size[y];//size[x]表示x的子树大小
			if(op[y].low

你可能感兴趣的:([POI2008]BLO-Blockade,洛谷之提高历练地,强连通分量)