hdu6165 FFF at Valentine 强联通分量+拓扑排序

来源:互联网 发布:picplaypost同类软件 编辑:程序博客网 时间:2024/06/10 15:05

题目大意:T个样例,n个节点,m条有向边(不存在重边),问能不能找到一条 经过每个点仅且一次的通路。

利用tarjan缩点为DAG,在该图中确定其拓扑排序是否唯一,若唯一,则存在着这样一条通路。


#include<stdio.h>#include<string.h>#include<queue>using namespace std;#define LL long longconst int inf=0x3f3f3f3f;const int maxn=1005;const int maxm=6005;int g[maxn][maxn];int vis[maxn];int n,m;int head[maxn],tot;int low[maxn],dfn[maxn],stackk[maxn],belong[maxn];int index,top;int scc;bool instack[maxn];int num[maxn];int indegree[maxn];struct edge{    int v;    int next;} edge[maxm];void addedge(int u,int v){    edge[tot].v=v;    edge[tot].next=head[u];    head[u]=tot++;}void tarjan(int u){    int v;    low[u]=dfn[u]=++index;    stackk[top++]=u ;    instack[u]=true;    for(int i=head[u]; i!=-1; i=edge[i].next)    {        v=edge[i].v;        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=stackk[--top];            instack[v]=false;            belong[v]=scc;            num[scc]++;        }        while(v!=u);    }}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));    memset(g,0,sizeof(g));    memset(indegree,0,sizeof(indegree));}int main(){    int t;    scanf("%d",&t);    while(t--)    {        init();        scanf("%d%d",&n,&m);        int u,v;        for(int i=0; i<m; i++)        {            scanf("%d%d",&u,&v);            addedge(u,v);        }        if(m<n-1)        {            printf("Light my fire!\n");        }        else        {            int flag=0;            solve(n);            if(scc==1)            {                printf("I love you my love and our love save us!\n");            }            else            {                for(int u=1; u<=n; u++)                {                    for(int vv=head[u]; vv!=-1; vv=edge[vv].next)                    {                        int v=edge[vv].v;                        int ub=belong[u],vb=belong[v];                        if(ub!=vb)                        {                            if(g[ub][vb]==0)                            {                                g[ub][vb]=1;                                indegree[vb]++;                            }                        }                    }                }                queue<int>q;                for(int i=1; i<=scc; i++)                {                    if(!indegree[i])                    {                        q.push(i);                    }                }                while(!q.empty())                {                    if(q.size()>1)                    {                        flag=1;                        break;                    }                    int u=q.front();                    q.pop();                    for(int v=1; v<=scc; v++)                    {                        if(g[u][v]==1)                        {                            indegree[v]--;                            if(!indegree[v])                            {                                q.push(v);                            }                        }                    }                }                if(flag)                    printf("Light my fire!\n");                else                {                    printf("I love you my love and our love save us!\n");                }            }        }    }    return 0;}


阅读全文
0 0