桥:
连通图中存在的必经之路,我们成为桥,如果把此路断开,连通图便会变成两个图
判断是否是桥的方式(low[v]>dfn[u])
题目链接
AC代码:
#include<bits/stdc++.h>
using namespace std;
//桥
#define maxn 10005
struct node
{
int a,b;//代表两个端点
} temp[maxn];
bool cmp(node x,node y)//结构体快排
{
if(x.a!=y.a)
return x.a<y.a;
return x.b<y.b;
}
vector<int>vec[maxn];
int dfn[maxn];//辅助时间戳
int low[maxn];//最早时间戳
int times,n,road;
void init()
{
times=road=0;
memset(temp,0,sizeof(temp));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(vec,0,sizeof(vec));
}
void dfs(int u,int fa)//求桥
{
dfn[u]=low[u]=++times;
for(int i=0; i<vec[u].size(); i++)
{
int v=vec[u][i];
if(!dfn[v])
{
dfs(v,u);
low[u]=min(low[u],low[v]);
}
if(low[v]>dfn[u])//把桥存入结构体
{
node road_point;
road_point.a=min(u,v);
road_point.b=max(u,v);
temp[road++]=road_point;
}
if (fa!=v)
{
low[u]=min(low[u],dfn[v]);
}
}
}
int main()
{
while(~scanf("%d",&n))
{
init();
int t=n;
while(t--)
{
int u,num;
scanf("%d (%d)",&u,&num);//起始节点和数量
while(num--)
{
int v;
scanf("%d",&v);
vec[u].push_back(v);
}
}
for(int i=0; i<n; i++)
{
if(!dfn[i])
dfs(i,-1);
}
sort(temp,temp+road,cmp);
printf("%d critical links\n",road);
for(int i=0; i<road; i++)
printf("%d - %d\n",temp[i].a,temp[i].b);
printf("\n");
}
}