您的位置:首页 > 其它

7_13_A题 SPF (tarjan求割点)

2016-09-04 15:37 316 查看

7_13_A题 SPF (tarjan求割点)

简单题意

给出一个图,问删去某个点后,这个图会被分成几块

思路

很显然,先求割点,只有割点在删去后才会形成新的联通块,所以先用tarjan求个割点,然后如果割点是搜索开始点且儿子数量大于等于2,他的儿子数量就是联通块的数量,否则割点的连通块数量就是儿子数量+1,这个可以通割点的性质来证;

代码

#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;

const int maxn = 1e3+5;

vector <int> G[maxn];
int dfn[maxn],low[maxn];
int bricnt = 0,times = 0,child = 0;
int ans[maxn];
void init(){
for(int i = 0 ; i <= maxn ; i ++){
G[i].clear();
}
child = bricnt = times = 0;
memset(dfn,-1,sizeof dfn);
memset(low,-1,sizeof low);
memset(ans,0,sizeof ans);
}

inline void addedge(int from, int to){
G[from].push_back(to);
G[to].push_back(from);
}

void Tarjan(int cur,int from){
bool flag = true;
dfn[cur] = low[cur] = times++;
for(int i = 0 ; i < G[cur].size(); i ++){
int to = G[cur][i];
if(dfn[to] == -1){
Tarjan(to,cur);
low[cur] = min(low[cur],low[to]);
if(low[to] >= dfn[cur]){
ans[cur] ++;
}
}
else
low[cur] = min(low[cur], dfn[to]);

4000
}
}

int main(){
int n,m;
int kas = 1;
while(~scanf("%d", &n)&&n){
int maxl = 0;
init();
scanf("%d", &m);
maxl = max(maxl,n);
maxl = max(maxl,m);
addedge(n,m);
while(~scanf("%d", &n)&&n){
scanf("%d", &m);
addedge(n,m);
maxl = max(maxl,n);
maxl = max(maxl,m);
}

Tarjan(1,0);
printf("Network #%d\n",kas++);
if(ans[1] > 0) ans[1]--;
bool flag = true;
for(int i = 1 ; i <= maxl; i ++){
if(ans[i]){
printf("  SPF node %d leaves %d subnets\n",i,ans[i]+1);
flag = false;
}
}
if(flag)
puts("  No SPF nodes");
puts("");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: