0
点赞
收藏
分享

微信扫一扫

Redundant Paths POJ - 3177

​​点击打开链接​​

边双连通分量模板 两个版本

第一个改自kuangbin模板 第二个自己xjb写的 感觉点与边双连通分量都没必要写单独的模板 求出割点与割边再dfs就好

 

#include <stdio.h>
#include <stack>
#include <cstring>
#include <algorithm>
using namespace std;

struct node
{
int v;
int next;
int flag;
};

stack <int> stk;
node edge[20010];
int first[5010],dfn[5010],low[5010],book[5010],belong[5010],degree[5010];
int n,m,num,cnt1,cnt2,ans;

void addedge(int u,int v)
{
edge[num].v=v;
edge[num].next=first[u];
edge[num].flag=0;
first[u]=num++;
return;
}

void dfs(int u,int fa)
{
int i,v;
stk.push(u);
num++;
dfn[u]=num;
low[u]=num;
book[u]=1;
for(i=first[u];i!=-1;i=edge[i].next)
{
v=edge[i].v;
if(v==fa) continue;
if(dfn[v]==0)
{
dfs(v,u);
if(low[u]>low[v])
{
low[u]=low[v];
}
if(low[v]>dfn[u])
{
cnt1++;
edge[i].flag=1;
edge[i^1].flag=1;
}
}
else if(book[v]==1&&low[u]>dfn[v])
{
low[u]=dfn[v];
}
}
if(dfn[u]==low[u])
{
cnt2++;
while(!stk.empty())
{
v=stk.top();
stk.pop();
book[v]=0;
belong[v]=cnt2;
if(u==v) break;
}
}
return;
}

void tarjan()
{
int i,j;
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(book,0,sizeof(book));
memset(belong,0,sizeof(belong));
memset(degree,0,sizeof(degree));
num=0,cnt1=0,cnt2=0;
for(i=1;i<=n;i++)
{
if(dfn[i]==0)
{
dfs(i,-1);
}
}
for(i=1;i<=n;i++)
{
for(j=first[i];j!=-1;j=edge[j].next)
{
if(edge[j].flag==1)
{
degree[belong[i]]++;
}
}
}
ans=0;
for(i=1;i<=cnt2;i++)
{
if(degree[i]==1) ans++;
}
return;
}

int main()
{
int i,u,v;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(first,-1,sizeof(first));
num=0;
for(i=1;i<=m;i++)
{
scanf("%d%d",&u,&v);
addedge(u,v);
addedge(v,u);
}
tarjan();
printf("%d\n",(ans+1)/2);
}
return 0;
}

 

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

struct node
{
int v;
int next;
int flag;
};

node edge[20010];
int first[5010],dfn[5010],low[5010],book[5010],belong[5010],degree[5010];
int n,m,num,tot;

void addedge(int u,int v)
{
edge[num].v=v;
edge[num].next=first[u];
edge[num].flag=0;
first[u]=num++;
return;
}

void dfsI(int cur,int pre)
{
int cnt,i,v;
num++;
dfn[cur]=num,low[cur]=num;
cnt=0;
for(i=first[cur];i!=-1;i=edge[i].next)
{
v=edge[i].v;
if(!dfn[v])
{
dfsI(v,cur);
low[cur]=min(low[cur],low[v]);
if(low[v]>dfn[cur])
{
edge[i].flag=1;
edge[i^1].flag=1;
}
}
else if(v==pre)
{
if(cnt>0) low[cur]=min(low[cur],dfn[v]);
cnt++;
}
else
{
low[cur]=min(low[cur],dfn[v]);
}
}
return;
}

void dfsII(int cur)
{
int i,v;
for(i=first[cur];i!=-1;i=edge[i].next)
{
v=edge[i].v;
if(!edge[i].flag&&!book[v])
{
book[v]=1;
belong[v]=tot;
dfsII(v);
}
}
return;
}

void tarjan()
{
int i,u,v,ans;
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
num=0;
for(i=1;i<=n;i++)
{
if(!dfn[i]) dfsI(i,-1);
}
memset(book,0,sizeof(book));
memset(belong,0,sizeof(belong));
memset(degree,0,sizeof(degree));
tot=0;
for(i=1;i<=n;i++)
{
if(!book[i])
{
book[i]=1;
belong[i]=++tot;
dfsII(i);
}
}
for(u=1;u<=n;u++)
{
for(i=first[u];i!=-1;i=edge[i].next)
{
v=edge[i].v;
if(belong[u]!=belong[v])
{
degree[belong[u]]++,degree[belong[v]]++;
}
}
}
ans=0;
for(i=1;i<=tot;i++)
{
if(degree[i]==2) ans++;
}
printf("%d\n",(ans+1)/2);
return;
}

int main()
{
int i,u,v;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(first,-1,sizeof(first));
num=0;
for(i=1;i<=m;i++)
{
scanf("%d%d",&u,&v);
addedge(u,v);
addedge(v,u);
}
tarjan();
}
return 0;
}

 


 

 

 

 


举报

相关推荐

0 条评论