SPF
64-bit integer IO format: %lld Java class name: Main
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
Source
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <climits> 7 #include <vector> 8 #include <queue> 9 #include <cstdlib> 10 #include <string> 11 #include <set> 12 #include <stack> 13 #define LL long long 14 #define pii pair<int,int> 15 #define INF 0x3f3f3f3f 16 using namespace std; 17 const int maxn = 1010; 18 vector<int>g[maxn]; 19 bool iscut[maxn]; 20 int dfn[maxn],low[maxn],cnt,vis[maxn]; 21 void tarjan(int u,int fa) { 22 dfn[u] = low[u] = ++cnt; 23 vis[u] = 1; 24 int son = 0; 25 for(int i = 0; i < g[u].size(); i++) { 26 if(!vis[g[u][i]]) { 27 tarjan(g[u][i],u); 28 son++; 29 low[u] = min(low[u],low[g[u][i]]); 30 if(fa == -1 && son > 1 || fa != -1 && low[g[u][i]] >= dfn[u]) 31 iscut[u] = true; 32 } else if(vis[g[u][i]] == 1) low[u] = min(low[u],dfn[g[u][i]]); 33 } 34 vis[u] = 2; 35 } 36 void dfs(int u) { 37 vis[u] = 1; 38 for(int i = 0; i < g[u].size(); i++) 39 if(!vis[g[u][i]]) dfs(g[u][i]); 40 } 41 void init() { 42 memset(vis,0,sizeof(vis)); 43 memset(iscut,false,sizeof(iscut)); 44 for(int i = 0; i < maxn; i++) g[i].clear(); 45 } 46 int main() { 47 int i,j,u,v,ks = 1,n,son; 48 bool flag; 49 while(scanf("%d",&u),u) { 50 n = 0; 51 init(); 52 scanf("%d",&v); 53 n = max(max(u,v),n); 54 g[u].push_back(v); 55 g[v].push_back(u); 56 while(scanf("%d",&u),u) { 57 scanf("%d",&v); 58 n = max(max(u,v),n); 59 g[u].push_back(v); 60 g[v].push_back(u); 61 } 62 flag = true; 63 tarjan(1,-1); 64 printf("Network #%d\n",ks++); 65 for(i = 1; i <= n; i++) { 66 if(iscut[i]) { 67 flag = false; 68 son = 0; 69 memset(vis,0,sizeof(vis)); 70 vis[i] = 1;//记得把路锁死 71 for(j = 0; j < g[i].size(); j++) { 72 if(!vis[g[i][j]]) { 73 son++; 74 dfs(g[i][j]); 75 } 76 } 77 printf(" SPF node %d leaves %d subnets\n",i,son); 78 } 79 } 80 if(flag) puts(" No SPF nodes"); 81 puts(""); 82 } 83 return 0; 84 }
不用再次dfs的方案:
去掉该关节点u,将原来的连通图分成几个连通分量?答案如下:
(1)如果关节点u是根结点,则有几个子女,就分成几个连通分量。
(2)如果关节点u不是根节点,则有n个子女w,使得low[w]>= dfn[u],则去掉该点,分成了n+1个连通分量。
注意:第二条的儿子数不同于第一个条件的儿子数。。。第二个多了个约束
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 const int maxn = 1010; 7 struct arc { 8 int to,next; 9 arc(int x = 0,int y = -1) { 10 to = x; 11 next = y; 12 } 13 }; 14 arc e[maxn*100]; 15 int head[maxn],dfn[maxn],low[maxn],cut[maxn],tot,scc,idx; 16 void add(int u,int v) { 17 e[tot] = arc(v,head[u]); 18 head[u] = tot++; 19 } 20 void tarjan(int u,int fa) { 21 dfn[u] = low[u] = idx++; 22 int son = 0,gson = 0; 23 bool flag = true,iscut = false; 24 for(int i = head[u]; ~i; i = e[i].next) { 25 if(flag && e[i].to == fa) { 26 flag = false; 27 continue; 28 } 29 if(dfn[e[i].to] == -1) { 30 tarjan(e[i].to,u); 31 son++; 32 low[u] = min(low[u],low[e[i].to]); 33 if(fa == -1 && son >= 2) iscut = true; 34 if(fa != -1 && low[e[i].to]>= dfn[u]) iscut = true,gson++; 35 } else if(e[i].to != fa) low[u] = min(low[u],dfn[e[i].to]); 36 } 37 if(iscut && fa == -1) cut[u] = son-1; 38 else if(iscut && fa != -1) cut[u] = gson; 39 } 40 int main() { 41 int u,v,kase = 1; 42 while(scanf("%d",&u),u) { 43 scanf("%d",&v); 44 memset(head,-1,sizeof(head)); 45 memset(cut,0,sizeof(cut)); 46 memset(dfn,-1,sizeof(dfn)); 47 memset(low,-1,sizeof(low)); 48 idx = tot = 0; 49 add(u,v); 50 add(v,u); 51 int up = max(u,v); 52 while(scanf("%d",&u),u) { 53 scanf("%d",&v); 54 add(u,v); 55 add(v,u); 56 up = max(up,max(u,v)); 57 } 58 for(int i = 1; i <= up; ++i) 59 if(dfn[i] == -1) tarjan(i,-1); 60 int ans = 0; 61 printf("Network #%d\n",kase++); 62 for(int i = 1; i <= up; ++i) { 63 if(cut[i]) { 64 printf(" SPF node %d leaves %d subnets\n",i,cut[i]+1); 65 ans++; 66 } 67 } 68 if(!ans) puts(" No SPF nodes"); 69 puts(""); 70 } 71 return 0; 72 }