題目大意:給出一個有向圖,問你這個圖中是否對於任意兩點\(u,v\),都至少知足\(u\to v\)(\(u\)可到達\(v\),下同)或\(v\to u\)中的一個。git
一看就是套路的圖論題,咱們先把邊連起來。spa
考慮一個很基本的性質:在一個強連通份量的點兩兩可達code
因而確定先Tarjan縮一波點。而後咱們獲得了一個DAG排序
接下來就是考慮是否有兩個點(固然是縮點以後的了)互不可達。string
這個能夠直接跑一邊拓撲排序。而後看一下是否在某個時刻有兩個點的入度爲零便可。it
CODEio
#include<cstdio> #include<cctype> #include<cstring> using namespace std; const int N=1005; struct edge { int to,next; }e[N*6],ne[N*6]; int head[N],nhead[N],t,n,m,x,y,cnt,tot,sum,dfn[N],low[N],col[N],stack[N],ru[N],q[N],top; bool vis[N]; inline char tc(void) { static char fl[100000],*A=fl,*B=fl; return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++; } inline void read(int &x) { x=0; char ch; while (!isdigit(ch=tc())); while (x=(x<<3)+(x<<1)+ch-'0',isdigit(ch=tc())); } inline void add(int x,int y) { e[++cnt].to=y; e[cnt].next=head[x]; head[x]=cnt; } inline void nadd(int x,int y) { ne[++cnt].to=y; ne[cnt].next=nhead[x]; nhead[x]=cnt; } inline void clear(void) { memset(head,-1,sizeof(head)); memset(e,-1,sizeof(e)); memset(nhead,-1,sizeof(nhead)); memset(ne,-1,sizeof(ne)); memset(dfn,0,sizeof(dfn)); memset(vis,0,sizeof(vis)); memset(col,0,sizeof(col)); memset(ru,0,sizeof(ru)); cnt=tot=sum=top=0; } inline int min(int a,int b) { return a<b?a:b; } inline void Tarjan(int now) { dfn[now]=low[now]=++tot; vis[now]=1; stack[++top]=now; for (register int i=head[now];i!=-1;i=e[i].next) if (!dfn[e[i].to]) Tarjan(e[i].to),low[now]=min(low[now],low[e[i].to]); else if (vis[e[i].to]) low[now]=min(low[now],dfn[e[i].to]); if (dfn[now]==low[now]) { vis[now]=0; col[now]=++sum; while (now!=stack[top]) { vis[stack[top]]=0; col[stack[top--]]=sum; } --top; } } inline bool top_sort(void) { register int i,H=0,T=0; for (i=1;i<=sum;++i) if (!ru[i]) q[++T]=i; while (H<T) { if (T-H>1) return 0; int now=q[++H]; for (i=nhead[now];i!=-1;i=ne[i].next) if (!(--ru[ne[i].to])) q[++T]=ne[i].to; } return 1; } int main() { //freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout); register int i,j; read(t); while (t--) { clear(); read(n); read(m); for (i=1;i<=m;++i) read(x),read(y),add(x,y); for (i=1;i<=n;++i) if (!dfn[i]) Tarjan(i); for (cnt=0,i=1;i<=n;++i) for (j=head[i];j!=-1;j=e[j].next) if (col[i]!=col[e[j].to]) nadd(col[i],col[e[j].to]),++ru[col[e[j].to]]; if (top_sort()) puts("I love you my love and our love save us!"); else puts("Light my fire!"); } return 0; }