POJ 1523 SPF 割边与割点
来源:互联网 发布:mysql 转义符号 编辑:程序博客网 时间:2024/05/01 15:09
本题要求出割点,并算出每个割点将图分成几个分支。
用tarjan算法求的割点,然后对每个割点,dfs求有多少个分支
每点的数是不一定的,我用的set存的点,vector存的图
求多少个分支就是:如果i是割点,就对与i相连的点的分支进行dfs标记,
假如与i相连的第j个点标记完了,标记第j+1个点时,发现j+1点标记过了,则j+1点和之前的某点在同一分支上,则不 sum++;
大概就是这样,自己画图感受一下吧!
注意:每组用例后腰输出一个空行,”那个“之前还有两个空格
#include<stdio.h>#include<string.h>#include<algorithm>#include<vector>#include<set>using namespace std;set<int> s;int low[1010],dfn[1010],vis[1010],shi[1010];int f[1010];vector<int> q[1010];int n,m,ntime,root,flag,flag1;//flag判断是否有割点,flag1判断是否输入结束void dfs(int u,int fa)//递归标记被走过的点{for(int i=0;i<q[u].size();i++){int v=q[u][i];if(v!=fa && shi[v]==0){shi[v]=1;dfs(v,u);}}}void tarjan(int u,int father)//求low[]和dfn[]{f[u]=father;int i,j,k;low[u]=dfn[u]=ntime++;for(i=0;i<q[u].size();i++){int v=q[u][i];if(!dfn[v]){tarjan(v,u);low[u]=min(low[u],low[v]);}else if(father!=v)low[u]=min(low[u],dfn[v]);}}void count(){int nroot=0,i;tarjan(root,0);set<int>::iterator it=s.begin();for(it++;it!=s.end();it++){int v=f[*it];if(v==root)nroot++;else{if(dfn[v]<=low[*it]){vis[v]=1;flag=1;}}}if(nroot>1) {vis[root]=1;flag=1;}int sum;for(it=s.begin();it!=s.end();it++){if(vis[*it]==1){memset(shi,0,sizeof(shi));sum=0;int u=*it;shi[u]=1;for(i=0;i<q[u].size();i++){int v=q[u][i];if(shi[v]==0)//与个点相连的v点没标记过{sum++;shi[v]=1;//标记该点dfs(v,u);//标记以该点为根节点的分支}}printf(" SPF node %d leaves %d subnets\n",u,sum);}}}int main(){int i,j,k,ans=0;memset(vis,0,sizeof(vis));//各种初始化memset(dfn,0,sizeof(dfn));memset(low,0,sizeof(low));memset(f,0,sizeof(f));for(i=0;i<1010;i++)q[i].clear();s.clear();flag=0;flag1=0;while(scanf("%d",&n)!=EOF){if(n!=0) {flag1=1;scanf("%d",&m);q[n].push_back(m);q[m].push_back(n);s.insert(n);s.insert(m);continue;}if(flag1==0) break;set<int>::iterator it=s.begin();root=*it;ntime=1;ans++;printf("Network #%d\n",ans);count();if(flag==0)printf(" No SPF nodes\n");printf("\n");memset(vis,0,sizeof(vis));//各种初始化memset(dfn,0,sizeof(dfn));memset(low,0,sizeof(low));memset(f,0,sizeof(f));for(i=0;i<1010;i++)q[i].clear();s.clear();flag=0;flag1=0;}return 0;}
刚才又和同学交流了一下,求割点的分支那个不用dfs,
对于割点u,找i的儿子v,也就是点v满足f[v]==u,如果low[v]>=dfn[u],则sum++; 具体原理我也不是太懂。。自己研究一下吧
另外,如果u是根节点,则不用sum++,如果u不是根节点,他的父亲还有一个分支,所以要sum++;
#include<stdio.h>#include<string.h>#include<algorithm>#include<vector>#include<set>using namespace std;set<int> s;int low[1010],dfn[1010],vis[1010];int f[1010];vector<int> q[1010];int n,m,ntime,root,flag,flag1;void tarjan(int u,int father){f[u]=father;int i,j,k;low[u]=dfn[u]=ntime++;for(i=0;i<q[u].size();i++){int v=q[u][i];if(!dfn[v]){tarjan(v,u);low[u]=min(low[u],low[v]);}else if(father!=v)low[u]=min(low[u],dfn[v]);}}void count(){int nroot=0,i;tarjan(root,0);set<int>::iterator it=s.begin();for(it++;it!=s.end();it++){int v=f[*it];if(v==root)nroot++;else{if(dfn[v]<=low[*it]){vis[v]=1;flag=1;}}}if(nroot>1) {vis[root]=1;flag=1;}int sum;for(it=s.begin();it!=s.end();it++){if(vis[*it]==1){sum=0;int u=*it;if(u!=root) //如果是根节点,则不用sum++,如果不是根节点,他的父亲还有一个分支,所以要sum++;sum++;for(i=0;i<q[u].size();i++){int v=q[u][i];if(f[v]==u && low[v]>=dfn[u]) //这判断一下{sum++;}}printf(" SPF node %d leaves %d subnets\n",u,sum);}}}int main(){int i,j,k,ans=0;memset(vis,0,sizeof(vis));memset(dfn,0,sizeof(dfn));memset(low,0,sizeof(low));memset(f,0,sizeof(f));for(i=0;i<1010;i++)q[i].clear();s.clear();flag=0;flag1=0;while(scanf("%d",&n)!=EOF){if(n!=0) {flag1=1;scanf("%d",&m);q[n].push_back(m);q[m].push_back(n);s.insert(n);s.insert(m);continue;}if(flag1==0) break;set<int>::iterator it=s.begin();root=*it;ntime=1;ans++;printf("Network #%d\n",ans);count();if(flag==0)printf(" No SPF nodes\n");printf("\n");memset(vis,0,sizeof(vis));memset(dfn,0,sizeof(dfn));memset(low,0,sizeof(low));memset(f,0,sizeof(f));for(i=0;i<1010;i++)q[i].clear();s.clear();flag=0;flag1=0;}return 0;}
- POJ 1523 SPF 割边与割点
- [割点] poj 1523 SPF
- POJ-1523 SPF 割点
- 【POJ】1523 SPF 割点
- POJ - 1523 SPF(割点)
- POJ--1523 SPF(割点)
- POJ 1523 SPF【割点】
- POJ 1523 SPF 割点
- POJ 1523 SPF (割点)
- Poj 1523 SPF(割点 + tarjan算法)
- TOJ 2018 POJ 1523 SPF / 割点
- POJ 1523 SPF(割点)
- POJ-1523 SPF (割点[Tarjan])
- POJ 1523 SPF (割点)
- POJ 1523 SPF(割点所割连通分量数)
- POJ 1523 SPF(割点所割连通分量数)
- POJ 1523 SPF(割点所割连通分量数)
- poj 1523 SPF 输出割点及割点分割的点集数目
- 深入了解Javascript(图解)
- 堆与栈的区别
- O'Reilly's CD bookshelf
- struts2的时间类型转换器
- codility上的问题 之二 Alpha 2010
- POJ 1523 SPF 割边与割点
- iOS: NSData的方法isEqualToData:
- 读写AT24C512的问题(续)
- xml解析
- 飘逸的python - 优雅的执行程序
- 单链表的运算之建立单链表【转载】
- iOS: NSData的方法length
- 职场生存法则之四
- 利用手工编码的方式对srtus2进行输入验证