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

解题思路:首先将图简化,比如假设图里有一个环,那么,这环内两个点肯定是能相互到达的,那么就不用考虑这环内的点了,很简单就想到用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. 【Codeforces 1137C】Museums Tour

    Codeforces 1137 C 题意:给一个有向图,一周有\(d\)天,每一个点在每一周的某些时刻会开放,现在可以在这个图上从\(1\)号点开始随意地走,问最多能走到多少个开放的点.一个点如果重复 ...

  2. golang 转换markdown文件为html

    使用blackfriday go get -u gopkg.in/russross/blackfriday.v2 go: package markdown import ( "fmt&quo ...

  3. 【第196期】Drupal7 Features模块与 Drupal8 Configuration Management 模块对比

    Drupal 8 最好和最受欢迎的部分之一是新的配置管理系统. 该系统使开发人员很容易将配置导出到代码中.在此之前,开发人员不得不依赖于由Features.Strongarm.UUID.Feature ...

  4. Yarn 入门

    Yarn 是快速.可靠.安全的 js 包管理器. 关键词: nodejs, 包管理, yarn 简介 Yarn 是快速.可靠.安全的 js 包管理器. 快速 - Yarn 会缓存它下载的每个包,所以无 ...

  5. Python代码转c#部分参考样例

    最近在做一部分Pyhton代码转c#代码的工作,以下案例亲自都测试过,现整理出来希望对有帮助的同学提供参考: Python | C# *:first-child{margin-top:0 !impor ...

  6. Linux下部署Samba服务环境的操作记录

    关于Linux和Windows系统之间的文件传输,很多人选择使用FTP,相对较安全,但是有时还是会出现一些问题,比如上传文件时,文件名莫名出现乱码,文件大小改变等问题.相比较来说,使用Samba作为文 ...

  7. .apply()用法和call()的区别

    Js apply方法详解我在一开始看到javascript的函数apply和call时,非常的模糊,看也看不懂,最近在网上看到一些文章对apply方法和call的一些示例,总算是看的有点眉目了,在这里 ...

  8. A. Vasya and Chocolate

    链接 [http://codeforces.com/contest/1065/problem/A] 分析 一个公式完事 代码 #include<bits/stdc++.h> using n ...

  9. ShowHand

    实验目的: Github基本源代码控制方法 利用Junit4进行程序模块的测试,回归测试 编码规范的考量 C/Java等基本程序设计语言的运用. 实验过程: import java.util.Arra ...

  10. [2017BUAA软工]第0次作业

    第0次作业 Part 1:结缘计算机 1. 你为什么选择计算机专业?你认为你的条件如何?和这些博主比呢? 我跟这篇博客中的作者相似的地方在于,我们都在一个比较早的阶段接触了计算机,我家乡的经济在全国来 ...