首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >强连通专题

强连通专题

作者头像
用户1624346
发布于 2018-04-17 08:14:25
发布于 2018-04-17 08:14:25
97900
代码可运行
举报
文章被收录于专栏:calmoundcalmound
运行总次数:0
代码可运行

POJ 2762 Going from u to v or from v to u?

题意:判断该图的任意两点是否可达

分析:tarjan后进行缩点,缩点后再建图,判断该图是否为单链式图形(只有一个叶结点)         判断能到达该点的节点个数是否等于bcnt

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include<stdio.h>
#include<string.h>
#include<vector>
#include<stack>
using namespace std;
const int MN=2011;
vector<int>edge[MN];
vector<int>SCC[MN];
stack<int>s;

int low[MN],dfn[MN];
int instack[MN],stap[MN];
int belong[MN];
int num[MN];
int ind[MN];
int tp,p;
int bcnt;

void tarjan(int x)
{
    low[x]=dfn[x]=++tp;
    stap[++p]=x;
    instack[x]=1;
    for(int i=0;i<edge[x].size();i++)
    {
        int v=edge[x][i];
        if(dfn[v]==-1)
        {
            tarjan(v);
            if(low[x]>low[v])
               low[x]=low[v];
        }
        else if(instack[v] && dfn[v]<low[x])
               low[x]=dfn[v];
    }
    if(low[x]==dfn[x])
    {
        int top;
        do
        {
            top=stap[p];
            belong[top]=bcnt;
            instack[top]=0;
            p--;
        }while(x!=top);
        bcnt++;
    }
}

void topsort()
{
    memset(num,0,sizeof(num));
    int i,u,v;
    while(!s.empty())
        s.pop();
    for(int i=0;i<bcnt;i++)
        if(ind[i]==0)
        {
            s.push(i);
            num[i]++;
        }
    while(!s.empty())
    {
        u=s.top();
        s.pop();
        for(int i=0;i<SCC[u].size();i++)
        {
            v=SCC[u][i];
            if(--ind[v]==0)
            {
                s.push(v);
                num[v]=num[u]+1;
            }
        }
    }
}

int main()
{
    int T,n,m,i,a,b,j;
    scanf("%d",&T);
    while(T--)
    {
        bcnt=tp=p=0;
        scanf("%d%d",&n,&m);
        memset(dfn,-1,sizeof(dfn));
        memset(low,0,sizeof(low));
        memset(instack,0,sizeof(instack));
        memset(belong,0,sizeof(belong));
        memset(ind,0,sizeof(ind));
        for(i=1;i<=n;i++)
        {
            edge[i].clear();
            SCC[i].clear();
        }
        for(i=0;i<m;i++)
        {
            scanf("%d%d",&a,&b);
            edge[a].push_back(b);
        }
        for(i=1;i<=n;i++)
        {
            if(dfn[i]==-1) tarjan(i);
        }
        for(i=1;i<=n;i++)
        {
            for(j=0;j<edge[i].size();j++)
            {
                int x=belong[i];
                int y=belong[edge[i][j]];
                if(x!=y)
                {
                     SCC[x].push_back(y);
                     ind[y]++;
                }
            }
        }
        topsort();
        int ans=-1;
        for(i=0;i<bcnt;i++)
        {
            ans=max(ans,num[i]);
        }
       // printf("%d\n",ans);
        if(bcnt==ans) printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}

POJ 2553  Popular Cows

题意:若牛A崇拜牛B,牛B崇拜牛C,则牛A崇拜牛C,问总共有多少只牛受到其他所有牛的崇拜

分析:若有环存在,则该环里的所有牛都互相崇拜,则可将环看成是一个点,后再构图,若想存在某个         点的牛收到其他所有牛的崇拜,则该图必定是单链式图形(只有一个叶结点)         tarjan缩点反向建图,然后只有一个入度为0

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include<stdio.h>
#include<string.h>
#include<vector>
#include<stack>
using namespace std;
const int MN=11000;
vector<int>SCC[MN];
vector<int>edge[MN];
stack<int>s;

int low[MN],dfn[MN];
int instack[MN],stap[MN];
int belong[MN];
int num[MN];
int ind[MN];
int sum[MN];
int tp,p;
int bcnt;
int n,m;
int cnt;
int pos;

void tarjan(int x)
{
    low[x]=dfn[x]=++tp;
    stap[++p]=x;
    instack[x]=1;
    for(int i=0;i<edge[x].size();i++)
    {
        int v=edge[x][i];
        if(dfn[v]==-1)
        {
            tarjan(v);
            if(low[x]>low[v])
               low[x]=low[v];
        }
        else if(instack[v] && dfn[v]<low[x])
             low[x]=dfn[v];
    }
    if(low[x]==dfn[x])
    {
        int top;
        do
        {
            top=stap[p];
            belong[top]=bcnt;
            sum[bcnt]++;
            instack[top]=0;
            p--;
        }while(x!=top);
        bcnt++;
    }
}

void topsort()
{
    int u,v;
    stack<int>s;
    memset(num,0,sizeof(num));
    for(int i=0;i<bcnt;i++)
    {
        if(ind[i]==0)
        {
            s.push(i);
            pos=i;
            cnt++;
        }
    }
}

int main()
{
    int i,j;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        memset(dfn,-1,sizeof(dfn));
        memset(low,0,sizeof(low));
        memset(instack,0,sizeof(instack));
        memset(belong,0,sizeof(belong));
        memset(ind,0,sizeof(ind));
        memset(sum,0,sizeof(sum));
        bcnt=tp=p=0;
        for(i=1;i<=n;i++)
        {
            edge[i].clear();
            SCC[i].clear();
        }
        for(i=0;i<m;i++)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            edge[a].push_back(b);
        }
        for(i=1;i<=n;i++)
        {
            if(dfn[i]==-1) tarjan(i);
        }
        for(i=1;i<=n;i++)
        {
            for(j=0;j<edge[i].size();j++)
            {
                int x=belong[i];
                int y=belong[edge[i][j]];
                if(x!=y)
                {
                    SCC[y].push_back(x);
                    ind[x]++;
                }
            }
        }
        int ans=0;
        cnt=0;
        topsort();
        if(cnt==1) printf("%d\n",sum[pos]);
        else printf("0\n");
    }
    return 0;
}

 POJ 2553  The Bottom of a Graph

题意:求出所有sink集合,sink集合的定义若v可达w,则w必定也可达v,求出所有的叶结点便可          而头节点不可以的原因是若v属于V,w不属于V,而v可达w,但是w不可达v,所以不可以          至于叶结点呢,v可达w,其中w必定都属于V集合

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
using namespace std;
const int MN=5010;
vector<int>SCC[MN];
vector<int>edge[MN];

int low[MN],dfn[MN];
int instack[MN],stap[MN];
int belong[MN];
int num[MN];
int ind[MN];
int rem[MN];
int tp,p;
int bcnt;
int n,m;
int cas;

void tarjan(int x)
{
    low[x]=dfn[x]=++tp;
    stap[++p]=x;
    instack[x]=1;
    for(int i=0; i<edge[x].size(); i++)
    {
        int v=edge[x][i];
        if(dfn[v]==-1)
        {
            tarjan(v);
            if(low[x]>low[v])
                low[x]=low[v];
        }
        else if(instack[v] && dfn[v]<low[x])
            low[x]=dfn[v];
    }
    if(low[x]==dfn[x])
    {
        int top;
        do
        {
            top=stap[p];
            belong[top]=bcnt;
            instack[top]=0;
            p--;
        }
        while(x!=top);
        bcnt++;
    }
}

void topsort()
{
    for(int i=0; i<bcnt; i++)
    {
        if(ind[i]==0)
        {
            for(int j=1; j<=n; j++)
            {
                if(belong[j]==i) rem[cas++]=j;
            }
        }
    }
}

bool cmp(int a,int b)
{
    return a<b;
}

int main()
{
    int i,w,v,j;
    while(scanf("%d",&n) && n)
    {
        scanf("%d",&m);
        tp=p=bcnt=cas=0;
        memset(dfn,-1,sizeof(dfn));
        memset(low,0,sizeof(low));
        memset(instack,0,sizeof(instack));
        memset(belong,0,sizeof(belong));
        memset(ind,0,sizeof(ind));
        for(i=0; i<=n; i++)
        {
            edge[i].clear();
            SCC[i].clear();
        }
        for(i=0; i<m; i++)
        {
            scanf("%d%d",&w,&v);
            edge[w].push_back(v);
        }
        for(i=1; i<=n; i++)
        {
            if(dfn[i]==-1) tarjan(i);
        }
        for(i=1; i<=n; i++)
        {
            for(j=0; j<edge[i].size(); j++)
            {
                int x=belong[i];
                int y=belong[edge[i][j]];
                if(x!=y)
                {
                    SCC[y].push_back(x);
                    ind[x]++;
                }
            }
        }
        topsort();
        sort(rem,rem+cas,cmp);
        printf("%d",rem[0]);
        for(i=1; i<cas; i++)
        {
            printf(" %d",rem[i]);
        }
        printf("\n");

    }
    return 0;
}

 POJ 1523 SPF

题意: 找出割点,且将割点拿掉后,存在几个连通分量 分析:   构建一棵dfs树,序列dfn[i]为深度优先数,表示dfs时访问i节点的序号,low[i]表示从i节点出发能访问到的最小的深度优先数。             当且仅当节点u满足如下两个条件之一时,u为割点:             1.u为dfs树的根,且u至少有两个子节点。             2.u不是dfs树的根,至少存在一个节点v是u的子节点,且low[v]>=dfn[u]。             若u为割点,记subnets[u]为u的子节点数,则去掉u后,图被分成subnets[u]+1个部分(每个子节点的部分和u的祖先的部分),若u为dfs树的根,则分                                                   成subnets[u]个部分(根节点没有祖先)。         以上全部算法均在dfs过程中完成。

割点模板

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int MN=1111;

struct Edge
{
    int to,next;
} edge[MN<<2];
int dfn[MN];
int low[MN];
int head[MN<<2];
int subnet[MN];
int E;
int tp;
int root;
int vis[MN];

void Init()
{
    memset(dfn,-1,sizeof(dfn));
    memset(low,0,sizeof(low));
    memset(head,-1,sizeof(head));
    memset(subnet,0,sizeof(subnet));
    memset(vis,0,sizeof(vis));
    E=tp=0;
}

void Add(int a,int b)
{
    edge[E].to=b;
    edge[E].next=head[a];
    head[a]=E++;
}

void tarjan(int u,int fa){  //割点模板
    int son=0;
    vis[u]=1;
    dfn[u]=low[u]=++tp;
    for(int i=head[u];i!=-1;i=edge[i].next){
        int v=edge[i].to;
        if(vis[v]==1 && v!=fa)
            low[u]=min(low[u],dfn[v]);
        if(!vis[v]){
            tarjan(v,u);
            son++;
            low[u]=min(low[u],low[v]);
            if((u==root && son>1) || (u!=root && dfn[u]<=low[v]))
                subnet[u]++;   //cut[u] 表示u这个点割边数
        }
    }
    vis[u]=2;
}

int main()
{
    int i,cas=1,n,a,b,nodes;
    while(scanf("%d",&n) && n)
    {
        nodes=n;
        Init();
        scanf("%d",&b);
        Add(n,b);
        Add(b,n);
        while(scanf("%d",&a) && a)
        {
            scanf("%d",&b);
            if(nodes<a) nodes=a;
            if(nodes<b) nodes=b;
            Add(a,b);
            Add(b,a);
        }
        for(i=1; i<=nodes; i++)
        {
            if(dfn[i]==-1)
            {root=i;
                tarjan(i,-1);
                
            }
        }
        int flag=0;
        printf("Network #%d\n",cas++);
        for(i=1; i<=nodes; i++)
        {
            if(subnet[i]>=1)
            {
                flag=1;
                printf("  SPF node %d leaves %d subnets\n",i,subnet[i]+1);
            }
        }
        if(flag==0) printf("  No SPF nodes\n");
        puts("");
    }
    return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2013-07-14 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
​Python爬虫-BeautifulSoup详解
上一节我们已经可以获取到网页内容,但是获取到的却是一长串的 html 代码,并不是我们想要的数据。那这一节,我们就来看看怎么去解析这些网页,轻松的拿到我们想要的数据。
小一不二三
2019/12/31
1.6K0
​Python爬虫-BeautifulSoup详解
BeautifulSoup使用
Beautiful Soup将复杂HTML文档转换成一个复杂的树形结构,每个节点都是Python对象,所有对象可以归纳为4种: Tag , NavigableString , BeautifulSoup , Comment .
听城
2018/08/30
1.1K0
BeautifulSoup文档4-详细方法 | 用什么方法对文档树进行搜索?
BeautifulSoup的文档搜索方法有很多,官方文档中重点介绍了两个方法: find() 和 find_all() 下文中的实例,依旧是官网的例子: html_doc = """ <html><head><title>The Dormouse's story</title></head> <body> <p class="title"><b>The Dormouse's story</b></p> <p class="story">Once upon a time there were three
虫无涯
2023/02/22
1.1K0
BeautifulSoup4中文文档
1、解析html并以友好形式显示:BeautifulSoup(html_doc,'html.parser') print(soup.prettify()) html_doc = """ <html><head><title>The Dormouse's story</title></head> <body> <p class="title"><b>The Dormouse's story</b></p>
用户5760343
2022/05/14
4400
python︱HTML网页解析BeautifulSoup学习笔记
一、载入html页面信息 一种是网站在线的网页、一种是下载下来的静态网页。 1、在线网页 参考《python用BeautifulSoup库简单爬虫入门+案例(爬取妹子图)》中的载入内容: import
悟乙己
2018/01/02
3.4K0
Python 爬虫之网页解析库 BeautifulSoup
BeautifulSoup 是一个使用灵活方便、执行速度快、支持多种解析器的网页解析库,可以让你无需编写正则表达式也能从 html 和 xml 中提取数据。BeautifulSoup 不仅支持 Python 内置的 Html 解析器,还支持 lxml、html5lib 等第三方解析器。
keinYe
2019/08/01
1.4K0
Python爬虫之BeautifulSoup
Python爬虫之BeautifulSoup #BeautifulSoup模块简介和安装 from bs4 import BeautifulSoup #CSS 选择器:BeautifulSoup4 #和lxml 一样,Beautiful Soup 也是一个HTML/XML的解析器 #主要的功能也是如何解析和提取 HTML/XML 数据。 #模块下载安装:pip install bs4 #基础例子 html = """ <html><head><title>The Dormouse's story
yuanshuai
2022/08/22
4240
Python爬虫:我这有美味的汤,你喝吗
在前面的文章中已经讲过了正则表达式的使用方法了,但是如果正则表达式出现问题,那么得到的结果就不是我们想要的内容。熟悉前端的朋友肯定知道,对于一个网页来说,都有一定的特殊结构和层级关系,而且很多节点都用id和class来区分。所以可以借助网页的结构和属性来提取数据。
我被狗咬了
2021/01/13
2.6K0
Python爬虫:我这有美味的汤,你喝吗
python 爬虫之BeautifulS
import urllib2 url = 'http://www.someserver.com/cgi-bin/register.cgi' values = {} values['name'] = 'Michael Foord' values['location'] = 'Northampton' values['language'] = 'Python'
py3study
2020/01/15
8600
04.BeautifulSoup使用
例1: print(type(p.contents)) #list print(p.contents) #可通过索引获取它的某一个元素。
见贤思齊
2020/08/05
2.5K0
04.BeautifulSoup使用
python爬虫系列三:html解析大法
Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库。 它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式。 在爬虫开发中主要用的是
py3study
2020/01/03
8760
python爬虫系列三:html解析大法
Python爬虫库BeautifulSoup的介绍与简单使用实例
BeautifulSoup是一个可以从HTML或XML文件中提取数据的Python库,本文为大家介绍下Python爬虫库BeautifulSoup的介绍与简单使用实例其中包括了,BeautifulSoup解析HTML,BeautifulSoup获取内容,BeautifulSoup节点操作,BeautifulSoup获取CSS属性等实例
用户7081581
2020/03/18
2K0
Python学习笔记(BeautifulSoup选择器)
Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Beautiful Soup会帮你节省数小时甚至数天的工作时间。
python与大数据分析
2022/03/11
3600
Python爬虫(十四)_BeautifulSoup4 解析器
CSS选择器:BeautifulSoup4 和lxml一样,Beautiful Soup也是一个HTML/XML的解析器,主要的功能也是如何解析和提取HTML/XML数据。 lxml只会局部遍历,而Beautiful Soup是基于HTML DOM的,会载入整个文档,解析整个DOM树,因此时间和内存开销都会大很多,所以性能要低于lxml。 BeautifulSoup用来解析HTML比较简单,API非常人性化,支持CSS选择器、Python标准库中的HTML解析器,也支持lxml的XML解析器。 Bea
用户1174963
2018/01/17
9040
Python爬虫(十四)_BeautifulSoup4 解析器
python爬虫之BeautifulSoup
文章目录 1. python爬虫之BeautifulSoup 1.1. 简介 1.2. 安装 1.3. 创建BeautifulSoup对象 1.4. Tag 1.4.1. 注意: 1.4.2. get 1.4.3. string 1.4.4. get_text() 1.5. 搜索文档树 1.5.1. find_all( name , attrs , recursive , text , **kwargs ) 1.5.2. find( name , attrs , recursive , text , *
爱撒谎的男孩
2019/12/31
1.1K0
BeautifulSoup文档3-详细方法 | 如何对文档树进行遍历?
以下实例还是官网的例子: html_doc = """ <html><head><title>The Dormouse's story</title></head> <body> <p class="title"><b>The Dormouse's story</b></p> <p class="story">Once upon a time there were three little sisters; and their names were <a href="http://example.
虫无涯
2023/02/22
7120
Python爬虫扩展库BeautifulSoup4用法精要
BeautifulSoup是一个非常优秀的Python扩展库,可以用来从HTML或XML文件中提取我们感兴趣的数据,并且允许指定使用不同的解析器。由于beautifulsoup3已经不再继续维护,因此新的项目中应使用beautifulsoup4,目前最新版本是4.5.0,可以使用pip install beautifulsoup4直接进行安装,安装之后应使用from bs4 import BeautifulSoup导入并使用。下面我们就一起来简单看一下BeautifulSoup4的强大功能,更加详细完整的学
Python小屋屋主
2018/04/16
8140
网络爬虫 | Beautiful Soup解析数据模块
从HTML文件中提取数据,除了使用XPath,另一种比较常用的解析数据模块。Beautiful Soup模块中查找提取功能非常强大、方便,且提供一些简单的函数来导航、搜索、修改分析树等功能。Beautiful Soup模块是Python的一个HTML解析库,借助网页的结构和属性来解析网页(比正则表达式简单、有效)。Beautiful Soup自动将输入文档转换为Unicode编码,输出文档转换为utf-8编码。
数据STUDIO
2021/06/24
6770
Python爬虫之BeautifulSoup解析之路
上一篇分享了正则表达式的使用,相信大家对正则也已经有了一定的了解。它可以针对任意字符串做任何的匹配并提取所需信息。
Python数据科学
2018/08/06
2K0
Python爬虫之BeautifulSoup解析之路
二、爬虫基础库
request模块 安装 1 pip install requests 简单使用   import requests response=requests.get("https://movie.douban.com/cinema/nowplaying/beijing/") print(response.content) # 字节数据 print(response.text) # 字符数据 print(type(response)) # <class '
用户1214487
2018/01/24
1.9K0
二、爬虫基础库
相关推荐
​Python爬虫-BeautifulSoup详解
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验