Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 7678 | Accepted: 3489 |
Description
Node 3 is therefore a Single Point of Failure (SPF) for this network. Strictly, an SPF will be defined as any node that, if unavailable, would prevent at least one pair of available nodes from being able to communicate on what was previously a fully connected network. Note that the network on the right has no such node; there is no SPF in the network. At least two machines must fail before there are any pairs of available nodes which cannot communicate.
Input
Output
The first network in the file should be identified as "Network #1", the second as "Network #2", etc. For each SPF node, output a line, formatted as shown in the examples below, that identifies the node and the number of fully connected subnets that remain when that node fails. If the network has no SPF nodes, simply output the text "No SPF nodes" instead of a list of SPF nodes.
Sample Input
1 2
5 4
3 1
3 2
3 4
3 5
0 1 2
2 3
3 4
4 5
5 1
0 1 2
2 3
3 4
4 6
6 3
2 5
5 1
0 0
Sample Output
Network #1
SPF node 3 leaves 2 subnets Network #2
No SPF nodes Network #3
SPF node 2 leaves 2 subnets
SPF node 3 leaves 2 subnets
題意: 求割點 同時求出刪除當前點後,分成幾個連通分量。
思路:
tarjan演算法求割點。 tarjan處理強連通 其實都是基於dfs的。同時維護2個數組。 dfn[] 和 low[] 分別表示第i點時的深度,和通過能夠到達的祖先的深度。
求強連通的時候,如果low[i] == dfn[i] 說明棧內當前點以上的點 都是強連通塊裡面的。也就是說i的子樹中不能到達i的祖先。
在求割點的時候,如果low[v] > dfn[u](v是u的子節點)說明v不能到達u的祖先 說明刪除u後 v的子樹從原圖中分離。
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<string>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define INF 1000000001
#define MOD 1000000007
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define pi acos(-1.0)
using namespace std;
const int MAXN = ;
struct node
{
int to;
int next;
}edge[MAXN*];
int ind,pre[MAXN],dfn[MAXN],low[MAXN],num[MAXN],n,vis[MAXN];
void add(int x,int y)
{
edge[ind].to = y;
edge[ind].next = pre[x];
pre[x] = ind ++;
}
void dfs(int rt,int d)
{
vis[rt] = ;
dfn[rt] = low[rt] = d;
for(int i = pre[rt]; i != -; i = edge[i].next){
int t = edge[i].to;
if(!vis[t]){
dfs(t,d + );
low[rt] = min(low[rt],low[t]);
if(low[t] >= dfn[rt]){
num[rt] ++;
}
}
else {
low[rt] = min(low[rt],dfn[t]);
}
}
}
int main()
{
int x,y,ff = ;
while(){
n = ;
scanf("%d",&x);
if(!x)break;
scanf("%d",&y);
ind = , memset(pre,-,sizeof(pre));
add(x,y), add(y,x);
n = max(x,y);
while(){
scanf("%d",&x);
if(!x)break;
scanf("%d",&y);
n = max(n,x);
n = max(n,y);
add(x,y), add(y,x);
}
memset(vis,,sizeof(vis));
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
memset(num,,sizeof(num));
dfs(,);
int flag = ;
if(ff >= )printf("\n");
printf("Network #%d\n",++ff);
num[] = num[] ? num[] - : ;
for(int i = ; i <= n; i++){
if(num[i]){
flag = ;
printf(" SPF node %d leaves %d subnets\n",i,num[i] + );
}
}
if(!flag){
printf(" No SPF nodes\n");
}
}
return ;
}