大意:求割顶的数量以及删除割顶之后子图的数量。
思路:Tarjan算法求割顶,同POJ 1144 NetWork.
CODE1:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using
namespace std;
const
int MAXN =
100010;
const
int MAXM =
500010;
struct Edge
{
int v, next;
}edge[MAXM];
int dfn[MAXN], low[MAXN], sub[MAXN];
int first[MAXN];
int N, M;
int cnt, tot;
int u, v;
void read_graph(
int u,
int v)
{
edge[cnt].v = v;
edge[cnt].next = first[u], first[u] = cnt++;
}
void init()
{
cnt =
0;
tot =
0;
memset(first, -
1,
sizeof(first));
memset(dfn,
0,
sizeof(dfn));
}
void read_graph2()
{
scanf(
"
%d
", &v);
read_graph(u, v);
read_graph(v, u);
N = max(N, max(u, v));
while(scanf(
"
%d
", &u) && u)
{
scanf(
"
%d
", &v);
read_graph(u, v);
read_graph(v, u);
N = max(N, max(u, v));
}
}
void tarjan(
int u)
{
dfn[u] = low[u] = ++tot;
for(
int e = first[u]; e != -
1; e = edge[e].next)
{
int v = edge[e].v;
if(!dfn[v])
{
tarjan(v);
low[u] = min(low[u], low[v]);
if(dfn[u] <= low[v]) sub[u]++;
}
low[u] = min(low[u], dfn[v]);
}
}
void solve(
int root)
{
for(
int i =
1; i <= N; i++) sub[i] = (i == root)?
0:
1;
//直接将根节点赋值为0
tarjan(root);
int flag =
0;
for(
int i =
1; i <= N; i++)
{
if(sub[i] >
1)
{
flag =
1;
printf(
"
SPF node %d leaves %d subnets\n
", i, sub[i]);
}
}
if(!flag)
printf(
"
No SPF nodes\n
");
}
int main()
{
int times =
0;
while(scanf(
"
%d
", &u) && u)
{
init();
read_graph2();
if(times) printf(
"
\n
");
printf(
"
Network #%d\n
", ++times);
solve(
1);
}
return
0;
}
CODE2:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using
namespace std;
const
int MAXN =
100010;
const
int MAXM =
500010;
struct Edge
{
int v, next;
}edge[MAXM];
int dfn[MAXN], low[MAXN], sub[MAXN];
int first[MAXN];
int N, M;
int cnt, tot;
int u, v;
int root =
1;
inline
void read_graph(
int u,
int v)
{
edge[cnt].v = v;
edge[cnt].next = first[u], first[u] = cnt++;
}
inline
void init()
{
cnt =
0;
tot =
0;
memset(first, -
1,
sizeof(first));
memset(dfn,
0,
sizeof(dfn));
}
inline
void read_graph2()
{
scanf(
"
%d
", &v);
read_graph(u, v);
read_graph(v, u);
N = max(N, max(u, v));
while(scanf(
"
%d
", &u) && u)
{
scanf(
"
%d
", &v);
read_graph(u, v);
read_graph(v, u);
N = max(N, max(u, v));
}
}
inline
void Tarjan(
int u,
int fa)
{
int rootson =
0;
low[u] = dfn[u] = ++tot;
for(
int e = first[u]; e != -
1; e = edge[e].next)
{
int v = edge[e].v;
if(!dfn[v])
{
if(u == root)
//
处理根节点。
{
if(++rootson >
1) sub[u]++;
}
Tarjan(v, u);
low[u] = min(low[u], low[v]);
if(u != root && dfn[u] <= low[v]) sub[u]++;
//
根节点已经被处理过。
}
low[u] = min(low[u], dfn[v]);
}
}
inline
void solve()
{
int flag =
0;
for(
int i =
1; i <= N; i++) sub[i] =
1;
Tarjan(root, -
1);
for(
int i =
1; i <= N; i++)
{
if(sub[i] >
1)
{
flag =
1;
printf(
"
SPF node %d leaves %d subnets\n
", i, sub[i]);
}
}
if(!flag) printf(
"
No SPF nodes\n
");
}
int main()
{
int times =
0;
while(scanf(
"
%d
", &u) && u)
{
init();
read_graph2();
if(times) printf(
"
\n
");
printf(
"
Network #%d\n
", ++times);
solve();
}
return
0;
}