点双连通分量之割点
http://www.cnblogs.com/en-heng/p/4002658.html
这篇说得相当清楚
http://blog.csdn.net/fuyukai/article/details/51039788
我大概是个辣鸡吧
/(ㄒoㄒ)/~~
一会整个自己的板子弄上来估计就稳了
一会分析一下板子
放模板题
点双连通分量
POJ - 1523
喵喵喵
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<map>
using namespace std;
const int maxn = 1005;
bool vis[maxn];
int dfn[maxn],low[maxn],subnet[maxn];
int head[maxn];
int cnt, m ,index ,son;
struct edge
{
int v,next;
}e[maxn];
void add(int u, int v)
{
e[cnt].v= v;
e[cnt].next = head[u];
head[u] = cnt++;
}
void init()
{
m = son = cnt = 0;
index = 1;
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(subnet,0,sizeof(subnet));
memset(vis,false,sizeof(vis));
memset(head,-1,sizeof(head));
}
void Tarjan(int u)
{
vis[u] = true;
for(int i = head[u];i!=-1;i = e[i].next)
{
int v = e[i].v;
if(!vis[v])
{
index++;
low[v] = dfn[v] = index;
Tarjan(v);
low[u] = min(low[u], low[v]);
if(low[v] >= dfn[u])
{
u==1? son++ : subnet[u]++;
}
}
else
{
low[u] = min(low[u],dfn[v]);
}
}
}
int main()
{
int u,v,ca = 1;
while(scanf("%d",&u)!=EOF && u)
{
init();
scanf("%d",&v);
add(u,v);
add(v,u);
m = max(m,max(u,v));
while(scanf("%d",&u)!=EOF && u)
{
scanf("%d",&v);
add(u,v);
add(v,u);
m = max(m,max(u,v));
}
Tarjan(1);
if(son > 1)
{
subnet[1] = son-1;
}
printf("Network #%d\n",ca++);
bool flag = false;
for(int i=1;i<=m;i++)
{
if(subnet[i])
{
flag = true;
printf(" SPF node %d leaves %d subnets\n",i,subnet[i]+1);
}
}
if(!flag)
{
printf(" No SPF nodes\n");
}
printf("\n");
}
}
边双连通分量
POJ - 3352
喵喵喵
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<map>
using namespace std;
const int maxn = 1005;
struct node
{
int to,next;
} edge[maxn*5];
int head[maxn],dfn[maxn],low[maxn],stack[maxn],cou[maxn];
int n,m,time,cnt,top;
bool vis[maxn];
void init()
{
memset(vis,0,sizeof(vis));
memset(head,-1,sizeof(head));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(cou,0,sizeof(cou));
top = cnt = 0;
time = 1;
}
void addedge(int u, int v)
{
edge[cnt].to = v;
edge[cnt].next = head[u];
head[u] = cnt;
cnt++;
}
void dfs(int u,int fa)
{
dfn[u] = low[u] = time++;
vis[u] = true;
stack[top++] = u;
for(int i = head[u];i!=-1;i=edge[i].next)
{
int v = edge[i].to;
if(v!=fa && dfn[u] > dfn[v])
{
if(!vis[v])
{
dfs(v,u);
low[u] = min(low[u],low[v]);
}
else
{
low[u] = min(low[u], dfn[v]);
}
}
}
if(dfn[u] == low[u])
{
while(stack[top] != u && top>0)
{
low[stack[top-1]] = low[u];
top--;
vis[stack[top]] = false;
}
}
}
int main()
{
int u,v;
while(scanf("%d%d",&n,&m)!=EOF)
{
init();
for(int i=0;i<m;i++)
{
scanf("%d%d",&u,&v);
u--;
v--;
addedge(u,v);
addedge(v,u);
}
dfs(0,-1);
for(int i=0;i<n;i++)
{
for(int j=head[i]; j!=-1;j=edge[j].next)
{
if(low[i] != low[edge[j].to])
{
cou[low[i]]++;
cou[low[edge[j].to]] ++;
}
}
}
cnt = 0;
for(int i=0;i<=n;i++)
{
if(cou[i]/2==1) cnt++;
}
printf("%d\n",(cnt+1)/2);
}
}