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; }