题目链接:Network
题意:给出一个无向图,求有多少个割边,并按字典序输出
算是个求割边模板题,不过还要求字典序
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<vector>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int N=10010;
const int M=100010;
struct edge
{
int v,next,flag;
}e[M];
int dfn[N],low[N],tot,dfs_num,first[N];
vector<pair<int,int> >ans;
void add(int u,int v)
{
e[tot].v=v;
e[tot].flag=0;
e[tot].next=first[u];
first[u]=tot++;
}
void tarjan(int u,int pre)
{
dfn[u]=low[u]=++dfs_num;
for(int i=first[u];~i;i=e[i].next)
{
int v=e[i].v;
if(v==pre)continue;//去掉回来的边
if(!dfn[v])
{
tarjan(v,u);
low[u]=min(low[u],low[v]);
if(low[v]>dfn[u])
e[i].flag=e[i^1].flag=1;
}
else
low[u]=min(low[u],dfn[v]);
}
}
void init()
{
dfs_num=0,tot=0;
mem(first,-1);
mem(dfn,0);
mem(low,0);
ans.clear();
}
int main()
{
int n,u,v,m;
while(~scanf("%d",&n))
{
init();
for(int i=1; i<=n; i++)
{
scanf("%d (%d)",&u,&m);
for(int j=0; j<m; j++)
{
scanf("%d",&v);
//if(v<u)continue;
add(u,v);
add(v,u);
}
}
for(int i=0; i<n; i++)
if(!dfn[i])
tarjan(i,i);
for(int i=0; i<n; i++)
{
for(int j=first[i];~j;j=e[j].next)
{
int v=e[j].v;
if(v>i&&e[j].flag)
ans.push_back(make_pair(i,v));
}
}
sort(ans.begin(),ans.end());
printf("%d critical links\n",ans.size());
for(int i=0; i<ans.size(); i++)
printf("%d - %d\n",ans[i].first,ans[i].second);
puts("");
}
return 0;
}