点双
找到割点后 一直退栈
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