题目大意,给出一个无向图,找出所有的桥,按字典序输出即可、
输入的时候注意一下就行了,比较坑,好多空格和单括号
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
const int M = (N * 2);
struct node
{
int next;
int to;
}edge[M];
struct bri
{
int u;
int v;
}bridge[M]; //存储桥的两个端点
int head[N],DFN[N],low[N];
int Stack[N];
bool instack[N];
int tot, stop, _index, scc, cnt;
void init ()
{
memset (head, -1, sizeof(head));
memset (DFN, -1, sizeof(DFN));
memset (low, 0, sizeof(low));
memset (instack, 0, sizeof(instack));
tot = stop = cnt = scc = _index = 0;
}
void addedge (int from, int to)
{
edge[tot].to = to;
edge[tot].next = head[from];
head[from] = tot++;
}
int cmp (bri a, bri b)
{
if (a.u == b.u)
{
return a.v < b.v;
}
return a.u < b.u;
}
void tarjan (int u, int pre)
{
int v;
DFN[u]=low[u]= ++_index;
instack[u]=true;
Stack[stop++]=u;
for(int i=head[u];~i;i=edge[i].next)
{
v=edge[i].to;
if(v==pre)
{
continue;
}
if(DFN[v]==-1)
{
tarjan(v,u);
low[u]=min(low[u],low[v]);
if(DFN[u]<low[v]) //满足桥的条件
{
bridge[++cnt].u=u;
bridge[cnt].v=v;
if(bridge[cnt].u>bridge[cnt].v)
{
swap(bridge[cnt].u,bridge[cnt].v);
}
}
}
else if(instack[v])
{
low[u]=min(low[u],DFN[v]);
}
}
if(low[u]==DFN[u])
{
scc++;
do
{
v=Stack[--stop];
instack[v]=false;
}while(v!=u);
}
}
void solve (int n)
{
for (int i = 1; i <= n; ++i)
{
if (DFN[i] == -1)
{
tarjan(i, -1);
}
}
sort (bridge + 1, bridge + cnt + 1, cmp);
printf("%d critical links\n", cnt);
for (int i = 1; i <= cnt; ++i)
{
printf("%d - %d\n", bridge[i].u - 1, bridge[i].v - 1);
}
printf("\n");
}
int main()
{
#ifdef LOCAL
freopen("C:/input.txt", "r", stdin);
#endif
int n;
int u, v;
int num;
while (~scanf("%d", &n))
{
if (n == 0)
{
printf("0 critical links\n\n");
continue;
}
init();
for (int i = 1; i <= n; ++i)
{
scanf("%d", &u);
++u;
getchar();
getchar();
scanf("%d", &num);
getchar();
while (num--)
{
scanf("%d", &v);
++v;
addedge (u, v);
}
}
solve (n);
}
return 0;
}