题意:有一些网络通过一些线路连接,求关键的连接,也就是桥,如果删除这个链接那么会产生两个子树
分析:注意一下图不是连通图即可
*******************************************************************
#include<stdio.h>
#include<string.h>
#include<stack>
#include<algorithm>
using namespace std;
const int MAXN = 1005;
///构建邻接表
struct Edge{int v, next;}e[MAXN*MAXN];
int Head[MAXN], cnt;
void AddEdge(int u, int v)
{
e[cnt].v = v;
e[cnt].next = Head[u];
Head[u] = cnt++;
}
///记录桥
struct Bridge{int u, v;}bri[MAXN];
int bnt;
bool cmp(Bridge n1, Bridge n2)
{
if(n1.u != n2.u)
return n1.u < n2.u;
return n1.v < n2.v;
}
int f[MAXN];
int Dfn[MAXN], Low[MAXN], Index;
void InIt(int N)
{
cnt = bnt = Index = 0;
for(int i=0; i<=N; i++)
{
Head[i] = -1;
Dfn[i] = false;
}
}
void Tarjan(int u, int father)
{
f[u] = father;
Low[u] = Dfn[u] = ++Index;
for(int j=Head[u]; j!=-1; j=e[j].next)
{
int v = e[j].v;
if( !Dfn[v] )
{
Tarjan(v, u);
Low[u] = min(Low[u], Low[v]);
}
else if( v != father )
Low[u] = min(Low[u], Dfn[v]);
}
}
int main()
{
int N;
while(scanf("%d", &N) != EOF)
{
int i, u, v, M;
InIt(N);
for(i=0; i<N; i++)
{
scanf("%d (%d)", &u, &M);
while(M--)
{
scanf("%d", &v);
AddEdge(u, v);
}
}
for(i=0; i<N; i++)
{
if( !Dfn[i] )
Tarjan(i, i);
}
for(i=0; i<N; i++)
{
int u = f[i];
if( Low[i] > Dfn[u] )
{
bri[bnt].u = min(u, i);
bri[bnt++].v = max(u, i);
}
}
sort(bri, bri+bnt, cmp);
printf("%d critical links\n", bnt);
for(i=0; i<bnt; i++)
printf("%d - %d\n", bri[i].u, bri[i].v);
printf("\n");
}
return 0;
}