首页 > 其他分享 >点双/边双 连通分量

点双/边双 连通分量

时间:2023-09-25 22:23:39浏览次数:33  
标签:连通 点双 int void add dfn low include 边双

 

点双

  找到割点后 一直退栈 

http://ybt.ssoier.cn:8088/problem_show.php?pid=1521

include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include<stack>
using namespace std ;

 const int N=502;
 #define int long long
 
 vector<int> g[N],bk[N];
 stack<int> st; 
 int n,m,low[N],dfn[N],cut[N],pool,tot;
 
 void add(int x,int y){
 	g[x].push_back(y);
 }
 void init(){
 	    int i,x,y;
		for(i=0;i<N;i++) g[i].clear(),cut[i]=dfn[i]=low[i]=0; 
		pool=tot= 0;
		while(!st.empty()) st.pop();
		
		for(i=1;i<=m;i++){
			cin>>x>>y;
			n=max(n,max(x,y));
			add(x,y),add(y,x);
		}	
}
 void dfs(int x,int fa){
 	dfn[x]=low[x]=++pool; st.push(x);
	  
	  int c=0;
 	for(int y:g[x]){
	  if(!dfn[y]){
	  	c++;
	    dfs(y,x),low[x]=min(low[x],low[y]);
		if(!fa&&c>1||fa&&dfn[x]<=low[y]) cut[x]=1;
		
		if(dfn[x]<=low[y]){
			tot++; bk[tot].clear();
			
		    while(1){
		   	  int t=st.top(); st.pop(); 
		   	  bk[tot].push_back(t);
		   	  if(t==y) break;
		    } 
		   bk[tot].push_back(x);
		}
	  } 
	  else low[x]=min(low[x],dfn[y]);
	}
 }
 

 void sov(){
 	for(int i=1;i<=n;i++) 
			if(!dfn[i]) dfs(i,0); 
 	int c1=0,c2=1;
 	
 	for(int i=1;i<=tot;i++){
 		int cnt=0, siz=bk[i].size(); 
 		
	 	for(int x:bk[i])
	 		if(cut[x]) cnt++;
		  
	  	if(cnt==0) c1+=2, c2=c2*siz*(siz-1)/2;
	 	if(cnt==1) c1++, c2=c2*(siz-1);
	}
   cout<<c1<<' '<<c2<<'\n'; 
 }
signed main(){
 	int T=0;
 	while(cin>>m&&m){
 		init(); 
		cout<<"Case "<<++T<<": ";
		sov();
	}
 }

 

边双

 https://vjudge.csgrandeur.cn/problem/POJ-3352

#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include<stack>
using namespace std ;

 const int N=1e5;
 #define int long long
 
 vector<int> g[N];

 int n,m,low[N],dfn[N],pool;
 
 void add(int x,int y){ g[x].push_back(y); }
 
 void dfs(int x,int fa){
 	dfn[x]=low[x]=++pool; 
	  
 	for(int i=0;i<g[x].size();i++){
 		  int y =g[x][i]; if(fa==y) continue ;
		  if(!dfn[y]){
		  	 dfs(y,x) ; low[x] =min(low[x],low[y]) ;
		  } 
		  else if(dfn[x]>dfn[y]) low[x]=min(low[x],dfn[y]);
	}
 }
 
 
int in[N] ;
 void sov(){
 	for(int i=1;i<=n;i++) 
		if(!dfn[i]) dfs(i,0); 
 	
 	for(int i=1;i<=n;i++)
	 	 for(int e=0;e<g[i].size();e++){
	 	 	int y= g[i][e] ;
	 	 	if(low[i]!=low[y]) in[low[y]]++;
	 	 }
	 	
	int cnt=0 ;
	for(int i=1;i<=n;i++)
		if(in[i]==1) cnt++ ;
	cout <<(cnt+1)/2<<endl;
 }
signed main(){
		cin>>n>>m;
		for(int x,y,i=1;i<=m;i++){
			cin>>x>>y;
			add(x,y),add(y,x);
		}	
		sov() ;
 }
 
 

 

标签:连通,点双,int,void,add,dfn,low,include,边双
From: https://www.cnblogs.com/towboa/p/17729000.html

相关文章

  • POJ 2186-Popular Cows ---强连通分量
    本题让求有多少点 是图中所有点都可到达改点的定理:在一个有向图中,如果有一个节点的出度为0,并且仅有一个这样的点,则该图中所有的点都可到达该点先求出图的强连通分量,然后将每个强连通分量化为一个层次,求是否存在一个强连通分量,该分量的出度为一,并且仅有一个这样的分量,则该连通分量......
  • tarjan 求强连通分量
    for(inti=0;i<n;i++)//图可能是不连通的,因此要表里每个点 if(!dfn[i]) tarjan(i);voidtarjan(intu){ inti,v; dfn[u]=low[u]=ntime++; z.push(u); f[u]=1; for(i=0;i<q[u].size();i++){ v=q[u][i]; if(!dfn[v]){ tarjan(v); low[u]=min(low[u],low[v]);......
  • 强连通分量
    强连通图判定从一个点出发,可以遍历整张图,再将所有的边反向,从同一点出发,可以遍历整张图,则该图是强连通图Tarjan求有向图强连通分量\(\text{dfn[u]}\)表示点\(u\)的dfs序,\(\text{low[u]}\)表示点\(u\)可以走到的dfs序最小的点我们在dfs树上,当一个点的\(\text{low[u]}=\te......
  • tarjan强连通分量
    intscc[N],sc;//结点i所在scc的编号intsz[N]; //强连通i的大小//dfn(u)为搜到结点u时的次序编号//low(u)为u或u的子树能够追溯到的最早的栈中节点的次序号//当dfn(u)=low(u)时,以u为根的搜索子树上的所有节点是一个强连通分量voidtarjan(intu){ dfn[u]=low[u]......
  • 华为SAN存储在Red Hat系统下的主机连通性FAQ
    1、建立iSCSI连接后,主机系统无法重启现象主机系统和存储系统建立iSCSI连接后,主机系统重启失败。根因分析主机停止iSCSI服务时,session没有关掉。解决方案主机系统重启前,请先停止iSCSI服务,然后再重启主机。2、替换LUN后无法更新LUN的信息现象当替换LUN的时候(前后两个LUN使......
  • 《北文的树形连通块dp》
    想看原文可以看这个对于一些问题,让我们数颜色数,要知道数颜色数这个东西非常的不好维护。往往我们四种解决方法:直接暴力数只数最后一个出现的(如果有什么性质的话)容斥,减去算重的将每个分开来计算贡献本文着重讲解第三种和第四种。......
  • 图解Spark Graphx基于connectedComponents函数实现连通图底层原理
    原创/朱季谦第一次写这么长的graphx源码解读,还是比较晦涩,有较多不足之处,争取改进。一、连通图说明连通图是指图中的任意两个顶点之间都存在路径相连而组成的一个子图。用一个图来说明,例如,下面这个叫graph的大图里,存在两个连通图。左边是一个连接图,该子图里每个顶点都存在路......
  • tarjan求点双连通分量
    边双连通分量见tarjan求边双连通分量部分参考lyd《算法竞赛进阶指南》前置知识给定无向连通图\(G=(V,E)\)割点:若对于\(x\inV\),从图中删去x及其连边,\(G\)分裂成两个及以上不相连子图,那么x是\(G\)的割点时间戳:在深度优先访问时按照每个节点第一次被访问的时间顺......
  • tarjan求边双连通分量
    本文仅为作者的一些学习笔记,内容可能具有局限性,比如并未就“点双连通分量”进行整理。部分参考lyd《算法竞赛进阶指南》前置概念桥(割边):若\(e\inE\),如果删去e后图分裂成两个子图,那么e这条边就为桥(割边)。时间戳:在深度优先访问时按照每个节点第一次被访问的时间顺序,依次......
  • Tarjan 求强连通分量
    欢迎批评指正!前置芝士什么是强连通分量(\(\text{SCC}\))?强连通分量,一般指有向图的极大强连通子图,在这些子图中,所有点双向可达。dfs序:即dfs过程中访问点的顺序。dfs生成树:由dfs过程中访问的边组成的边集和原图的点集组成的树。树边,非树边:属于dfs过程中访问的边为......