http://www.bnuoj.com/v3/problem_show.php?pid=17935
题目描述:
给定一个无向图,并不一定是连通图,求所有的桥
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<algorithm>
const int MAXN=10010;
const int MAXM=100010;
using namespace std;
struct Edge{
int to,next;
bool cut;
}edge[MAXM];int head[MAXN],tot;
int Low[MAXN],DFN[MAXN],Stack[MAXN];
int Index,top;
bool Instack[MAXN];
bool cut[MAXN];
int add_block[MAXN];
int bridge;
void addedge(int u,int v){
edge[tot].to=v;
edge[tot].next=head[u];
edge[tot].cut=false;
head[u]=tot++;
}
void Tarjan(int u,int pre){
int v;
Low[u]=DFN[u]=++Index;
Stack[top++]=u;
Instack[u]=true;
int son=0;
for(int i=head[u];i!=-1;i=edge[i].next){
v=edge[i].to;
if(v==pre) continue;
if(!DFN[v]){
son++;
Tarjan(v,u);
if(Low[u]>Low[v]) Low[u]=Low[v];
if(Low[v]>DFN[u]){
bridge++;
edge[i].cut=edge[i^1].cut=true;
}
}
else if(Low[u]>DFN[v])
Low[u]=DFN[v];
}
Instack[u]=false;
top--;
}
void solve(int N){
memset(DFN,0,sizeof(DFN));
memset(Instack,false,sizeof(Instack));
Index=top=0;
bridge=0;
for(int i=1;i<=N;++i){
if(!DFN[i])
Tarjan(i,i);
}
printf("%d critical links\n",bridge);
vector<pair<int,int> >ans;
for(int u=1;u<=N;++u){
for(int i=head[u];i!=-1;i=edge[i].next){
if(edge[i].cut&&edge[i].to>u){
ans.push_back(make_pair(u,edge[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");
}
void init(){
tot=0;
memset(head,0xff,sizeof(head));
}
int main()
{
int n;
while(scanf("%d",&n)==1){
init();
int u,k,v;
for(int i=1;i<=n;++i){
scanf("%d (%d)",&u,&k);
u++;
while(k--){
scanf("%d",&v);
v++;
if(v<=u) continue;
addedge(u,v);
addedge(v,u);
}
}
solve(n);
}
return 0;
}