ZOJ1119(SPF)

题目链接:传送门

题目大意:一副无向图,问有多少个节点满足删除该节点后图不连通,对于每个满足条件的节点,输出节点编号及删除节点将图分为几个连通块。若没有节点满足则输出No SPF nodes

题目思路:tarjan算法求关节点入门题(也可用矩阵存图)

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstdlib>
  4 #include <cmath>
  5 #include <algorithm>
  6 #include <cstring>
  7 #include <stack>
  8 #include <cctype>
  9 #include <queue>
 10 #include <string>
 11 #include <vector>
 12 #include <set>
 13 #include <map>
 14 #include <climits>
 15 #define lson root<<1,l,mid
 16 #define rson root<<1|1,mid+1,r
 17 #define fi first
 18 #define se second
 19 #define ping(x,y) ((x-y)*(x-y))
 20 #define mst(x,y) memset(x,y,sizeof(x))
 21 #define mcp(x,y) memcpy(x,y,sizeof(y))
 22 #define Min(x,y) (x<y?x:y)
 23 #define Max(x,y) (x>y?x:y)
 24 using namespace std;
 25 #define gamma 0.5772156649015328606065120
 26 #define MOD 100000007
 27 #define inf 0x3f3f3f3f
 28 #define N 1000005
 29 #define maxn 1000050
 30 typedef long long LL;
 31 typedef pair<int,int> PII;
 32
 33 int n,m,head[1001],hcnt,son,num;
 34 int dfn[1001],low[1001],area[1001],vis[1001];
 35 int deep;
 36 struct Node{
 37     int to,next;
 38     Node(){}
 39     Node(int a,int b):to(a),next(b){}
 40 }node[2000800];
 41 inline void add(int x,int y){
 42     node[hcnt]=Node(y,head[x]);
 43     head[x]=hcnt++;
 44 }
 45
 46 void init(){
 47     num=0;  ///最大节点的编号
 48     hcnt=0;
 49     deep=1; ///深度搜索树的深度优先数(第几个被搜索)
 50     son=0;  ///记录根节点的子女个数
 51     low[1]=dfn[1]=1;  ///low表示节点能通过子女和回边到达的最小深度优先数
 52     mst(head,-1);     ///dfn表示节点的深度优先数
 53     mst(vis,0);
 54     mst(area,0);  ///记录删除某个节点后图被分成了几块
 55     vis[1]=1; ///标记节点是否访问过
 56 }
 57
 58 void dfs(int x){
 59     for(int i=head[x];~i;i=node[i].next){
 60         int e=node[i].to;
 61         if(vis[e]) low[x]=Min(low[x],dfn[e]);
 62         else{
 63             vis[e]=1;
 64             dfn[e]=low[e]=++deep;
 65             dfs(e);
 66             low[x]=Min(low[x],low[e]);
 67             if(low[e]>=dfn[x]){
 68                 if(x==1) ++son;
 69                 else ++area[x];
 70             }
 71         }
 72     }
 73 }
 74
 75 int main(){
 76     int i,j,group,Case=0,x,y;
 77     while(scanf("%d",&x)!=EOF&&x){
 78         init();
 79         num=Max(num,x);
 80         scanf("%d",&y);
 81         num=Max(num,y);
 82         add(x,y);
 83         add(y,x);
 84         while(scanf("%d",&x)&&x){
 85             num=Max(num,x);
 86             scanf("%d",&y);
 87             num=Max(num,y);
 88             add(x,y);
 89             add(y,x);
 90         }
 91         if(Case)printf("\n");
 92         printf("Network #%d\n",++Case);
 93         dfs(1);
 94         if(son>1)area[1]=son-1;
 95         int flag=0;
 96         for(i=1;i<=num;++i)if(area[i]){
 97             flag=1;
 98             printf("  SPF node %d leaves %d subnets\n",i,area[i]+1);
 99         }
100         if(!flag) printf("  No SPF nodes\n");
101     }
102     return 0;
103 }
时间: 2024-10-13 21:50:00

ZOJ1119(SPF)的相关文章

Postfix邮件系统安装与配置:Postfix,Cyrus-IMAP,Cyrus-sasl,Dovecot和SPF

最近发现邮件发送服务还是挺重要的.可能对于每天只有一百来封的邮件发送需求的个人博主来说,一个免费的邮箱提供的免费SMTP邮件发送服务就可以满足了,但是对于一些大型的网站.论坛和平台,每天的邮件发送量可以达到上万封以上,免费的邮件发送服务是不能满足需要了. 市场上已经有了不少的付费邮件发送服务,但是终归是第三方的邮件发送服务,在邮件发送方式.邮件内容等方面肯定要受到不少的限制.与其花大量的时间寻找更好的付费邮件服务,还不如自己动手利用VPS或者服务器搭建一个属于自己的邮件发送平台,搭建起来并不复杂

SPF(poj 1523) 割点入门

1 /***************************************** 2 SPF(poj 1523) 3 割点入门 4 http://poj.org/problem?id=1523 5 6 ******************************************/ 7 8 #include<iostream> 9 #include<algorithm> 10 #include<cstdio> 11 #include<cstring&

【POJ 1523】SPF(割点)

儿子数大于1的树根或者 Low[v] >= DFN[u]的非树根节点v 就是割点. #include <cstdio> #include <cstring> const int N = 1001; const int M = 1000010; struct Edge { int to,next; bool cut;//是否为桥的标记 }edge[M]; int head[N],tot; int Low[N],DFN[N],Stack[N]; int Index,top; bo

POJ1523 SPF(割点)

题目求一个无向图的所有割点,并输出删除这些割点后形成几个连通分量.用Tarjan算法: 一遍DFS,构造出一颗深度优先生成树,在原无向图中边分成了两种:树边(生成树上的边)和反祖边(非生成树上的边). 顺便求出每个结点的DFS序dfn[u] 和 每个结点能沿着它和它的儿子的返祖边达到的结点最小的DFS序low[u]. 一个点是割点当且仅当—— 这个点是生成树的根,且有x(x>=2)个的子树,删除这个点后就形成x个连通分量. 这个点不是树根,且其存在x(x>=1)个儿子的low值小于等于该点的d

SPF Tarjan算法求无向图割点(关节点)入门题

SPF 题目抽象,给出一个连通图的一些边,求关节点.以及每个关节点分出的连通分量的个数 邻接矩阵只要16ms,而邻接表却要32ms,  花费了大量的时间在加边上. //   time  16ms 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <string&

POJ-1523 SPF(tarjan求割点)

题目链接:http://poj.org/problem?id=1523 题目大意:有多组数据,要你求出每组数据的割点,并输出这个割点所在的块数 算法实现: 割点是什么:一个无向连通图去掉一个点及与这个点相连的后,这个无向图分为多个互不连通的子块,这个点则称为割点 时间戳是什么:在搜索时访问的最早时间 算法:tarjan算法 维护dfn[u]表示u的时间戳 low[u]表示u点所能回到的最早的祖先的时间戳 cut[u]表示u点所属于的块的数量 判断割点的条件  dfn[u]>=low[v]  //

POJ 1523 SPF 解题报告

思路:使用tarjan算法求出割点,在枚举去掉每一个割点所能形成的联通块的个数. 注意:后来我看了下别的代码,发现我的枚举割点的方式是比较蠢的方式,我们完全可以在tarjan过程中把答案求出来,引入一下讨论: 如果这个割点是根节点,在tarjan算法中搜到几个孩子结点(low[v] >= dfn[u]),他就能割出几个联通块,如果这个割点是孩子结点,那么他所形成的联通块的个数+1,因为他还有一条与父亲结点间接或直接相连的边. 代码如下: #include<map> #include<

poj 1523 SPF【点双连通求去掉割点后bcc个数】

SPF Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7246   Accepted: 3302 Description Consider the two networks shown below. Assuming that data moves around these networks only between directly connected nodes on a peer-to-peer basis, a

POJ 1523 SPF(无向图割顶)

SPF Description Consider the two networks shown below. Assuming that data moves around these networks only between directly connected nodes on a peer-to-peer basis, a failure of a single node, 3, in the network on the left would prevent some of the s