UVA 796 https://vjudge.net/problem/20839/origin
思路:
记录Tarjan求桥模板。
Ac代码:
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
struct node
{
int from,to,next,flag;
}e[1500000];
int cont,tot,cnt,n;
int head[150000];
int vis[150000];
int dfn[150000];
int low[150000];
int fa[150000];
void add(int from,int to)
{
e[cont].flag=0;
e[cont].to=to;
e[cont].next=head[from];
head[from]=cont++;
}
void tarjan(int u,int pre)
{
dfn[u]=low[u]=++cnt;
for(int i=head[u];i!=-1;i=e[i].next)
{
int v=e[i].to;
if(v == pre)continue;
if(!dfn[v])
{
tarjan(v,u);
if(low[u]>low[v])low[u]=low[v];
///桥
if(low[v]>dfn[u])
{
e[i].flag=1;
e[i^1].flag=1;
tot++;
}
}
else if(low[u]>dfn[v])
low[u]=dfn[v];
}
}
void Slove()
{
tot=0,cnt=0;
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++)if(vis[i]==0)tarjan(i,-1);
printf("%d critical links\n",tot);
vector<pair<int,int> >ans;
for(int u=1;u<=n;u++)
{
for(int i=head[u];i!=-1;i=e[i].next)
{
if(e[i].flag&&e[i].to>u)
{
ans.push_back(make_pair(u,e[i].to));
}
}
}
sort(ans.begin(),ans.end());
for(int i=0;i<ans.size();i++)
{
printf("%d - %d\n",ans[i].first-1,ans[i].second-1);
}
printf("\n");
}
int main()
{
while(~scanf("%d",&n))
{
cont=0;
memset(head,-1,sizeof(head));
for(int i=0; i<n; i++)
{
int u,num;
scanf("%d (%d)",&u,&num);
u++;
while(num--)
{
int v;
scanf("%d",&v);
v++;
if(v<=u)continue;
add(u,v);
add(v,u);
}
}
Slove();
}
return 0;
}