您的位置:首页 > 其它

poj 1523 SPF

2015-03-23 17:46 344 查看
题意:判断一个图中是否存在关节点。

分析:直接枚举n个点,然后dfs统计连通分量。dfs过了照着模版敲了个tarjan,还有点晕。

坑点:每个数据后要一个换行,而不是两个数据之间。

AC代码:

#include <iostream>
#include <algorithm>
#include <cstdio>

using namespace std;

const int maxn = 1005;

struct node{//静态链结点
int v;
int next;

node(){}
};

struct ad_list{
int list[maxn];
node arc[maxn*maxn];
int arc_cnt;

void clear(){
for(int i = 0; i < maxn; i++) list[i] = -1;
arc_cnt = 0;
}

void add(int u, int v){
arc[arc_cnt].v = v;
arc[arc_cnt].next = list[u];
list[u] = arc_cnt;
arc_cnt++;
}

};

int max_vex;
bool flag[maxn];//判断某个结点是否出现
ad_list t;
bool vis[maxn];//for dfs

bool input(){
int u,v;

//clear
t.clear();
max_vex = 0;
for(int i = 0; i < maxn; i++) flag[i] = false;

scanf("%d",&u);
if(u == 0) return false;
scanf("%d",&v);
t.add(u,v);
t.add(v,u);
max_vex = max(max_vex,u);
max_vex = max(max_vex,v);
flag[u] = true;
flag[v] = true;
while(1){
scanf("%d",&u);
max_vex = max(max_vex,u);
flag[u] = true;
if(u == 0) break;
scanf("%d",&v);
max_vex = max(max_vex,v);
flag[v] = true;
t.add(u,v);
t.add(v,u);
}
return true;
}

void dfs(int s){

for(int i = t.list[s]; i != -1; i = t.arc[i].next){
int v = t.arc[i].v;
if(!vis[v]){
vis[v] = true;
dfs(v);
}
}
}

void solve(){
static int case_cnt = 0;
bool ok = false;//存不存在在spf node

printf("Network #%d\n",++case_cnt);
for(int i = 1; i <= max_vex; i++){//依次尝试删除一个点
if(!flag[i]) continue;

//clear vis
for(int j = 1; j <= max_vex; j++) vis[j] = false;
vis[i] = true;//把点i删除

int cnt = 0;//连通分量
for(int j = 1; j <= max_vex; j++){//dfs求连通分量
if(!flag[j]) continue;
if(!vis[j]){
dfs(j);
cnt++;
}
}

if(cnt > 1){
ok = true;
printf("  SPF node %d leaves %d subnets\n",i,cnt);
}

}//end of for 1 to max_vex
if(!ok) puts("  No SPF nodes");
puts("");
}

int main(){
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
while(input()){
solve();
}

return 0;
}


tarjan代码:

#include <iostream>
#include <algorithm>
#include <cstdio>

using namespace std;

const int maxn = 1005;

struct node{//静态链结点
int v;
int next;

node(){}
};

struct ad_list{
int list[maxn];
node arc[maxn*maxn];
int arc_cnt;

void clear(){
for(int i = 0; i < maxn; i++) list[i] = -1;
arc_cnt = 0;
}

void add(int u, int v){
arc[arc_cnt].v = v;
arc[arc_cnt].next = list[u];
list[u] = arc_cnt;
arc_cnt++;
}

};

int max_vex;
bool flag[maxn];//判断某个结点是否出现
ad_list t;
int vis[maxn];//for dfs
int cnt;//记录dfs顺序
int low[maxn];//for tarjan
int subnet[maxn];//记录关节点能划分为多少个子图
int son;//根结点孩子的个数

bool input(){
int u,v;

//clear
t.clear();
max_vex = 0;
for(int i = 0; i < maxn; i++) flag[i] = false;

scanf("%d",&u);
if(u == 0) return false;
scanf("%d",&v);
t.add(u,v);
t.add(v,u);
max_vex = max(max_vex,u);
max_vex = max(max_vex,v);
flag[u] = true;
flag[v] = true;
while(1){
scanf("%d",&u);
max_vex = max(max_vex,u);
flag[u] = true;
if(u == 0) break;
scanf("%d",&v);
max_vex = max(max_vex,v);
flag[v] = true;
t.add(u,v);
t.add(v,u);
}
return true;
}

void dfs(int u){

for(int i = t.list[u]; i != -1; i = t.arc[i].next){
int v = t.arc[i].v;
if(!vis[v]){
vis[v] = low[v] = ++cnt;
dfs(v);
low[u] = min(low[u],low[v]);
if(low[v] >= vis[u]){
if(u != 1)subnet[u]++;
if(u == 1) son++;
}

}
else low[u] = min(low[u],vis[v]);//回边
}
}

void solve(){
static int case_cnt = 0;
bool ok = false;//存不存在在spf node

printf("Network #%d\n",++case_cnt);

//clear
cnt = 1; son = 0;
for(int i = 0; i <= max_vex; i++) {
subnet[i] = 0; vis[i] = 0;
}
low[1] = 1; vis[1] = 1;

dfs(1);
if(son > 1) subnet[1] = son-1;

for(int i = 1; i <= max_vex; i++){
if(subnet[i]){
ok = true;
printf("  SPF node %d leaves %d subnets\n",i,subnet[i]+1);
}
}
if(!ok) puts("  No SPF nodes");
puts("");
}

int main(){
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
while(input()){
solve();
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: