poj 1523 SPF

来源:互联网 发布:windows to go是什么 编辑:程序博客网 时间:2024/06/03 21:10

题意:判断一个图中是否存在关节点。


分析:直接枚举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;//cleart.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 visfor(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_vexif(!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;//cleart.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);//clearcnt = 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;}


0 0
原创粉丝点击