hdu6165 缩点,dfs

Posted 掉血菜鸡煮熟中

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu6165 缩点,dfs相关的知识,希望对你有一定的参考价值。

hdu6165    FFF at Valentine

题意:给出一个有向图,问任意两个点 a、b,是否可以从a到b,或者从b到a。

tags:主要是题意有点绕。。 只要 tarjan 缩点成 DAG图,再 dfs 判断一下在 DAG 图中是否有一条路径包含了所有点。

#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define rep(i,a,b) for (int i=a; i<=b; ++i)
#define per(i,b,a) for (int i=b; i>=a; --i)
#define mes(a,b)  memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define MP make_pair
#define PB push_back
#define fi  first
#define se  second
typedef long long ll;
const int N = 6005;

int n, m;
struct Edge{ int from, to, next; } e[N*2];
int Stack[N<<2], dfn[N], low[N], Belong[N], sz[N], head[N];
bool instack[N];
int top, tot, sum, tot1;
void Addedge(int u,int v) { e[tot]={u, v, head[u]}; head[u]=tot++; }
void Tarjan(int u)
{
    dfn[u]=low[u]=++tot1;
    Stack[top++]=u, instack[u]=1;
    for(int i=head[u]; i!=-1; i=e[i].next) {
        int v=e[i].to;
        if(dfn[v]==0) {
            Tarjan(v);
            low[u]=min(low[u], low[v]);
        }
        else if(instack[v]) low[u]=min(low[u], dfn[v]);
    }
    if(dfn[u]==low[u]) {
        sum++;
        while(top!=0) {
            int en=Stack[--top];
            instack[en]=0;
            Belong[en]=sum;
            sz[sum]++;
            if(en==u) break;
        }
    }
}
vector<int > G[N<<1];
int in[N], s1;
void Init()
{
    mes(head, -1);  mes(Stack, 0);  mes(dfn, 0);
    mes(Belong, 0);  mes(sz, 0);  mes(instack, false);
    mes(low, 0);
    mes(in, 0);
    rep(i,0,(N<<1)-1) G[i].clear();
    sum = tot = tot1 = top = s1 = 0;
}
bool dfs(int u)
{
    ++s1;
    if(s1==sum) return true;
    for(int i=0; i<G[u].size(); ++i)
    {
        if(dfs(G[u][i])) return true;
    }
    --s1;
    return false;
}
int main()
{
    int T;  scanf("%d", &T);
    while(T--)
    {
        scanf("%d%d", &n, &m);
        Init();
        int u, v;
        rep(i,1,m)
        {
            scanf("%d%d", &u, &v);
            Addedge(u, v);
        }
        rep(i,1,n) if(dfn[i]==0) Tarjan(i);
        bool flag=0;
        rep(i,0,tot-1)
        {
            u=Belong[e[i].from], v=Belong[e[i].to];
            if(u!=v)  G[u].PB(v), ++in[v];
        }
        int ro, num=0;
        rep(i,1,sum) if(in[i]==0) ro=i, ++num;
        if(num>1) flag=1;
        else if(!dfs(ro)) flag=1;
        if(flag==0) puts("I love you my love and our love save us!");
        else puts("Light my fire!");
    }

    return 0;
}

以上是关于hdu6165 缩点,dfs的主要内容,如果未能解决你的问题,请参考以下文章

hdu6165(拓扑排序+tarjan缩点)

2017 Multi-University Training Contest - Team 9 1005&&HDU 6165 FFF at Valentine强联通缩点+拓扑排序((代

hdu 6165

HDU 6165-强连通分量+拓扑

HDU 6165 FFF at Valentine

HDU 2242 考研路茫茫——空调教室(边双连通)