割边水题,套模板的题目。
#include <iostream>
#include <vector>
using namespace std;
const int N = 201;
bool bridge[N][N]; //bridge数组为1的说明是割边
int low[N], d[N];//Low数组保存最远祖先,d数组为深度
int color[N], bcnt;
vector<int> g[N];//用前需清空g[N]容器,bridge数组,color数组和bcnt
void dfs(int u, int parent, int deep )
{
color[u] = 1;
d[u] = low[u] = deep;
for(int i = 0; i < g[u].size(); i++ )
{
int v = g[u][i];
if(color[v] == 1 && v != parent)
low[u] = low[u] < d[v] ? low[u] : d[v];
if(color[v] == 0)
{
dfs(v, u, deep + 1);
low[u] = low[u] < low[v] ? low[u] : low[v];
if(low[v] > d[u]) //u v 是桥
{
bcnt++;
bridge[u][v] = bridge[v][u] = 1;
}
}
}
color[u] = 2;
}
int main()
{
int n;
while(~scanf("%d", &n))
{
memset(bridge, false, sizeof(bridge));
bcnt = 0;
for(int i = 0; i < N; i++)
{
g[i].clear();
color[i] = 0;
}
for(int i = 0; i < n; i++)
{
int a, b, c;
scanf("%d (%d)", &a, &c);
for(int j = 0; j < c; j++)
{
scanf("%d", &b);
g[a].push_back(b);
g[b].push_back(a);
}
}
for(int i = 0; i < n; i++)
{
if(!color[i]) dfs(i, 0, 0);
}
printf("%d critical links\n", bcnt);
for(int i = 0; i < n; i++)
{
for(int j = i + 1; j < n; j++)
{
if(bridge[i][j]) printf("%d - %d\n", i, j);
}
}
printf("\n");
}
return 0;
}