题意:就任意两个点能否到达;

解题思路:首先将图简化,比如假设图里有一个环,那么,这环内两个点肯定是能相互到达的,那么就不用考虑这环内的点了,很简单就想到用tarjan算法将环缩成一个点,然后就是判断缩完点后的图内任意两点能否互相到达了,能互相到达一定是有路径连接所有点的,就通过拓扑排序了,如果同一层的两点或以上的入度在排序时都为0时那么肯定不能到达,因为没有路径连接这两个点,这道题属于模板型的题,只要思路正确,是能写出来的,貌似还有暴力dfs的写法,还没去看;

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<queue>
using namespace std;
const int MAXN=2e5+5;
const int MAXM=5e5+5;
int head[MAXN],tot;
int low[MAXN],dfn[MAXN],sta[MAXN],bel[MAXN];//bel数组的值是1~scc
int index,top;
int scc;//强连通分量的个数
bool instack[MAXN];
int num[MAXN];//各个强连通分量包含点的个数,数组编号1~scc
//num数组不一定需要,结合实际情况
int n,m;

struct Edge
{
    int from,to,nxt;
}edge[MAXM];

void addedge(int u,int v)
{
    edge[tot].from=u;
    edge[tot].to=v;
    edge[tot].nxt=head[u];
    head[u]=tot++;
}//链式前向星存图;

void tarjan(int u)
{
    int v;
    low[u]=dfn[u]=++index;
    sta[top++]=u;
    instack[u]=true;
    for(int i=head[u];i!=-1;i=edge[i].nxt)
    {
        v=edge[i].to;
        if(!dfn[v])
        {
            tarjan(v);
            if(low[u]>low[v]) low[u]=low[v];
        }else if(instack[v]&&low[u]>dfn[v])
        low[u]=dfn[v];
    }
    if(low[u]==dfn[u])
    {
        scc++;
        do
        {
            v=sta[--top];
            instack[v]=false;
            bel[v]=scc;
            num[scc]++;
        }while(v!=u);
    }
}//tarjan算法算强联通图;

void solve(int n)
{
    memset(dfn,0,sizeof(dfn));
    memset(instack,false,sizeof(instack));
    memset(num,0,sizeof(num));
    index=scc=top=0;
    for(int i=1;i<=n;i++)
    {
        if(!dfn[i]) tarjan(i);
    }
}

void init()
{
    tot=0;
    memset(head,-1,sizeof(head));
}

int in[MAXN];
vector<int> G[MAXN];
void suodian()
{
    memset(in,0,sizeof(in));
    for(int i=1;i<=scc;i++) G[i].clear();
    for(int i=0;i<m;i++)
    {
        int u=bel[edge[i].from];
        int v=bel[edge[i].to];
        if(u!=v)
        {
            G[u].push_back(v);
            in[v]++;
        }
    }
    int cnt=0,p;
    for(int i=1;i<=scc;i++)
    {
        if(in[i]==0) {cnt++;p=i;}
    }
    if(cnt>=2) printf("Light my fire!\n");
    else
    {
        queue<int> q;
        while(!q.empty()) q.pop();
        q.push(p);
        bool flag=true;
        while(!q.empty())
        {
            int fs=q.front();
            q.pop();
            int du=0;
            int sz=G[fs].size();
            for(int i=0;i<sz;i++)
            {
                int to=G[fs][i];
                in[to]--;
                if(in[to]==0)
                {
                    du++;
                    q.push(to);
                }
            }
            if(du>=2) {flag=false;break;}
        }
        if(flag) printf("I love you my love and our love save us!\n");
        else printf("Light my fire!\n");
    }
}//缩点后的拓扑排序;

int main()
{

int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        init();
        int u,v;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&u,&v);
            addedge(u,v);
        }
        solve(n);
// cout<<scc<<endl;
// for(int i=1;i<=n;i++)
// {
// cout<<bel[i]<<endl;
// }
// cout<<num[1]<<" "<<num[2]<<endl;
        suodian();
    }
    return 0;
}

hdu6165(拓扑排序+tarjan缩点)的更多相关文章

  1. 判断单向连通图(拓扑排序+tarjan缩点)

    题意: 给你一个有向图,如果对于图中的任意一对点u和v都有一条从u到v的路或从v到u的路,那么就输出’Yes’,否则输出’No’. 理解:当出现两个及以上入度为0的点(有一个就可能是别人到它,有两个的 ...

  2. BZOJ 1194 [HNOI2006]潘多拉的盒子 (图论+拓扑排序+tarjan)

    题面:洛谷传送门 BZOJ传送门 标签里三个算法全都是提高组的,然而..这是一道神题 我们把这道题分为两个部分解决 1.找出所有咒语机两两之间的包含关系 2.求出咒语机的最长上升序列 我们假设咒语机$ ...

  3. P1347 排序 (拓扑排序,tarjan)

    题目 P1347 排序 解析 打开一看拓扑排序,要判环. 三种情况 有环(存在矛盾) 没环但在拓扑排序时存在有两个及以上的点入度为0(关系无法确定) 除了上两种情况(关系可确定) 本来懒了一下,直接在 ...

  4. 【Luogu P3387】缩点模板(强连通分量Tarjan&拓扑排序)

    Luogu P3387 强连通分量的定义如下: 有向图强连通分量:在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶 ...

  5. 【BZOJ-1924】所驼门王的宝藏 Tarjan缩点(+拓扑排序) + 拓扑图DP

    1924: [Sdoi2010]所驼门王的宝藏 Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 787  Solved: 318[Submit][Stat ...

  6. [模板]tarjan缩点+拓扑排序

    题目:给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 允许多次经过一条边或者一个点,但是,重复经过的点,权值只计算一次. 题目简述:先t ...

  7. [HAOI2006]受欢迎的牛 tarjan缩点 + 拓扑排序

    ---题面--- 题解: 首先tarjan缩点应该还是容易想到的,因为喜爱具有传递性,所以一个强联通分量里面的点实际上是全部等效的,所以我们可以缩成一个方便判断, 缩完点之后整张图就变成了一个有向无环 ...

  8. 【洛谷 P1073】 最优贸易 (Tarjan缩点+拓扑排序)

    题目链接 先\(Tarjan\)缩点,记录每个环内的最大值和最小值. 然后跑拓扑排序,\(Min[u]\)表示到\(u\)的最小值,\(ans[u]\)表示到\(u\)的答案,\(Min\)和\(an ...

  9. [luogu2272 ZJOI2007] 最大半连通子图 (tarjan缩点 拓扑排序 dp)

    传送门 题目描述 一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:?u,v∈V,满足u→v或v→u,即对于图中任意两点u,v,存在一条u到v的有向路径或者从v到u的有向 ...

随机推荐

  1. iScroll.js插件使用方法

    iScroll.js 用法参考 (share) 分享是传播.学习知识最好的方法 以下这篇文章是iScroll.js官网的中文翻译,尽管自己英文不好,但觉得原作者们翻译的这个资料还是可以的,基本用法介绍 ...

  2. Android应用更新-自动检测版本及自动升级

    原文 http://www.cnblogs.com/keyindex/articles/1819504.html 注:实质,把自己新版的APK放在可以下载的地方,先自己设置个通信,检查版本,我是直接放 ...

  3. IIS导入.pfx证书时报错:"A specified logon session does not exist. It may already have been terminated."

    在IIS中可以直接导入.pfx文件来给站点绑定https协议: 如果在导入.pfx文件时,不选择"Allow this certificate to be exported"的话 ...

  4. Scala学习(七)---包和引入

    包和引入 摘要: 在本篇中,你将会了解到Scala中的包和引入语句是如何工作的.相比Java不论是包还是引入都更加符合常规,也更灵活一些.本篇的要点包括: 1. 包也可以像内部类那样嵌套 2. 包路径 ...

  5. 1.RapidIO协议概述

    转自https://www.cnblogs.com/liujinggang/p/9925859.html 一.RapidIO背景介绍 RapidIO是由Motorola和Mercury等公司率先倡导的 ...

  6. [UWP 自定义控件]了解模板化控件(2.1):理解ContentControl

    UWP的UI主要由布局容器和内容控件(ContentControl)组成.布局容器是指Grid.StackPanel等继承自Panel,可以拥有多个子元素的类.与此相对,ContentControl则 ...

  7. Linux文件下载(转)

    wget是Linux最常用的下载命令, 一般的使用方法是: wget + 空格 + 要下载文件的url路径 例如: # wget http://www.linuxsense.org/xxxx/xxx. ...

  8. Slurm任务调度系统部署和测试(源码)(1)

    1. 概述1.1 节点信息2. 节点准备3. 部署NTP服务器4. 部署LDAP服务器5. 部署Munge认证服务6. 部署Mysql数据库服务7. 部署slurm7.1 创建slurm用户7.2 挂 ...

  9. SpringBoot日记——ElasticSearch全文检索

    看到标题的那一串英文,对于新手来说一定比较陌生,而说起检索,应该都知道吧. 这个ElasticSearch目前我们的首选,他主要有可以提供快速的存储.搜索.分析海量数据的作用.他是一个分布式搜索服务, ...

  10. UML图中类之间的关系:依赖,泛化,关联,聚合,组合,实现(转)

    UML图中类之间的关系:依赖,泛化,关联,聚合,组合,实现   类与类图 1) 类(Class)封装了数据和行为,是面向对象的重要组成部分,它是具有相同属性.操作.关系的对象集合的总称. 2) 在系统 ...