判断图是否单连通,先用强连通分图处理,再拓扑排序,需注意:
符合要求的不一定是链
拓扑排序列结果唯一,即在队列中的元素始终只有一个
#include<cstdio> #include<iostream> #include<cstdlib> #include<cstring> #include<string> #include<algorithm> #include<map> #include<queue> #include<vector> #include<cmath> #include<utility> #include<stack> using namespace std; typedef long long LL; const int N = 1008, INF = 0x3F3F3F3F; int dfn[N],id[N]; int lab,cnt; stack <int> st; int n, m; int head[N], tot; int indeg[N]; vector<int> g[N]; void init(){ memset(head, - 1,sizeof(head)); tot= 0; } struct Edge{ int to, next; }edge[20008]; void add(int u, int v){ edge[tot].to = v; edge[tot].next = head[u]; head[u] = tot++; } int dfs(int u){ int lowu=dfn[u]=++lab; st.push(u); for(int i = head[u];i!=-1;i=edge[i].next){ int v = edge[i].to; if(!dfn[v]){ int lowv = dfs(v); lowu = min(lowu, lowv); }else if(!id[v]) { lowu = min(lowu, dfn[v]); } } if(lowu == dfn[u]){ cnt++; while(1){ int x = st.top(); st.pop(); id[x] = cnt; if(x == u) break; } } return lowu; } int tarjan(){ for(int i=1;i<=n;i++) { dfn[i] = id[i] = 0; } lab=cnt=0; for(int i=1;i<=n;i++) { if(!dfn[i]){ dfs(i); } } return cnt; } //符合要求的不一定是链 //拓扑排序列结果唯一,即在队列中的元素始终只有一个 bool topsort(int n){ queue<int > q; int sum = 0; for(int i = 1; i <= n; i++){ if(indeg[i] == 0){ q.push(i); if(q.size() > 1){ return false; } } } while(!q.empty()){ int u = q.front(); q.pop(); sum++; for(int i= 0; i < g[u].size(); i++){ int v = g[u][i]; indeg[v]--; if(indeg[v] == 0){ q.push(v); } } if(q.size() > 1){ return false; } } if(sum != n){ return false; } return true; } int main(){ int t; cin>>t; while(t--){ init(); memset(indeg, 0, sizeof(indeg)); scanf("%d %d", &n, &m); while(m--){ int u, v; scanf("%d %d", &u, &v); add(u, v); } tarjan(); for(int i =1; i<= cnt; i++){ g[i].clear(); } for(int u = 1; u <= n; u++){ for(int i = head[u] ; ~i ; i = edge[i].next){ int v = edge[i].to; if(id[u] != id[v]){ indeg[id[v]]++; g[id[u]].push_back(id[v]); } } } if(topsort(cnt)){ printf("Yes "); }else{ printf("No "); } } return 0; }