hdu6165 FFF at Valentine 强联通缩点

来源:互联网 发布:misumi软件 编辑:程序博客网 时间:2024/06/10 05:04

https://vjudge.net/contest/181274#problem/E

自己不集中精力。debug到想哭。。而且一些反例没有想好。。比如
这里写图片描述
只能参考http://blog.csdn.net/Richie_ll/article/details/77488066

当然还有别的判断方法。。比如看能不能一条路径走完全部点。。
而且暴力的话也是可以的。。用bfs

stack<int>S;int cost[N];int uu[N<<1],fst[N],to[N<<1],nxt[N<<1],dfs_clock;int low[N],pre[N],e;int sccno[N];int scc_cnt;int in[N],out[N];int n,m;inline void add(int u,int v,int c){    uu[e]=u;cost[e]=c;to[e]=v;nxt[e]=fst[u];fst[u]=e++;}void dfs(int u){    low[u]=pre[u]=++dfs_clock;    S.push(u);    for(int i=fst[u];~i;i=nxt[i]){        int v=to[i];        if(!pre[v]){            dfs(v);            low[u]=min(low[v],low[u]);        }        else if(!sccno[v]){            low[u]=min(low[u],pre[v]);        }    }    if(pre[u]==low[u]){        scc_cnt++;        while(1){            int x=S.top();S.pop();            sccno[x]=scc_cnt;            if(x==u)break;        }    }}int vis[N];bool  solve(){    int num=0;    int num1=0;    int tmp=0;    mem(vis,0);    for(int i=1;i<=scc_cnt;++i){        if(out[i]==0)num++;        if(in[i]==0)num1++,tmp=i;    }    if(num>=2||num1>=2)return false;    queue<int>q;    for(int i=1;i<=scc_cnt;++i){        if(in[i]==0){in[i]--;q.push(i);}    }    int flag=1;    while(!q.empty()){        int x=q.front();q.pop();        flag--;        for(int i=fst[x];~i;i=nxt[i]){            if(cost[i]==0)continue;            int v=to[i];            in[v]--;            if(in[v]==0){                flag++;                in[v]--;                q.push(v);            }            if(flag>=2)return false;        }    }    return true;}int main(){    int T;sf("%d",&T);    while(T--){        mem(fst,-1);e=0;scc_cnt=0;        mem(vis,0);mem(sccno,0);dfs_clock=0;        mem(out,0);mem(in,0);mem(cost,0);mem(pre,0);mem(low,0);        sf("%d%d",&n,&m);        rep(i,1,m){            int u,v;sf("%d%d",&u,&v);            add(u,v,0);        }        for(int i=1;i<=n;++i){ if(!pre[i])dfs(i); }        int cnt=0;        int tmp=e;        for(int i=0;i<tmp;++i){            int u=uu[i],v=to[i];            if(sccno[u]!=sccno[v]){                add(sccno[u],sccno[v],1);                out[sccno[u]]++;in[sccno[v]]++;            }        }        if(!solve())puts("Light my fire!");        else puts("I love you my love and our love save us!");    }}
阅读全文
0 0