题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6165
题意:给出一个有向无自环,无重边的有向图,判断任意两点是否能到达(只要一个能抵达另一个即可)
这是做的第一道拓扑排序的题目,讲解可见:https://blog.csdn.net/qq_41713256/article/details/80805338
分析:只要求两点中任一点可到达另一点即可。首先强连通分量内部肯定是可以是任意到达的,我们先利用Tarjan进行缩点形成一个有向无环图(DAG),在这个基础上我们进行拓扑排序,只要存在一条路径连接所有点的话,那么肯定是可以到达了,基于此我们在拓扑排序时,如果每一层都只有一个点入度为0 ,就可以得到唯一的一条路径连接所有点了,也就是说这时候就可以到达了。
#include<bits/stdc++.h> #define maxn 1011 using namespace std; vector<int>G[maxn],new_G[maxn]; stack<int>s; int n,m; int dfn[maxn],vis[maxn],low[maxn],color[maxn],colornum,cnt,in[maxn]; //in数组记录入度 bool toposort(int n){ queue<int>q; int res=0; for(int i=1;i<=n;i++) //n 节点的总数 if(in[i]==0) q.push(i),res++; //将入度为0的点入队列 if(res>1) return 0; vector<int>ans; //ans 为拓扑序列,这个题目里没用到 while(!q.empty()) { //cout<<233<<endl; int p=q.front(); q.pop(); // 选一个入度为0的点,出队列 //cout<<p<<endl; ans.push_back(p); res=0; for(int i=0;i<new_G[p].size();i++) { int y=new_G[p][i]; //if(p==2)cout<<G[p][i]<<endl; in[y]--; if(in[y]==0) q.push(y),res++; //cout<<p<<" "<<y<<endl; } if(res>1) return 0; } return 1; } void tarjan(int x) { dfn[x]=low[x]=++cnt; s.push(x); vis[x]=true; for(int i=0;i<G[x].size();i++) { int q=G[x][i]; if (!dfn[q]) { tarjan(q); low[x]=min(low[x],low[q]); } else if (vis[q]) low[x]=min(low[x],dfn[q]); } if (low[x]==dfn[x]) { colornum++; int t; do{ t=s.top();s.pop(); color[t]=colornum; vis[t]=false; }while(t!=x); } } void init(int n){ colornum=0,cnt=0; memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(vis,0,sizeof(vis)); memset(color,0,sizeof(color)); memset(in,0,sizeof(in)); for(int i=1;i<=n;i++) G[i].clear(); } int main(){ int T;scanf("%d",&T); while(T--){ int n,m;scanf("%d%d",&n,&m); init(n);//初始化 for(int i=1;i<=m;i++){ int x,y;scanf("%d%d",&x,&y); G[x].push_back(y); } for(int i=1;i<=n;i++){ if(!dfn[i]) tarjan(i); } for(int i=1;i<=colornum;i++){//对新建的图初始化 new_G[i].clear(); } for(int i=1;i<=n;i++){ for(int j=0;j<G[i].size();j++){ if(color[i]!=color[G[i][j]]) in[color[G[i][j]]]++,new_G[color[i]].push_back(color[G[i][j]]); } } //cout<<endl<<colornum<<endl; if(toposort(colornum)){ printf("I love you my love and our love save us! "); } else printf("Light my fire! "); } return 0; }