For a directed graph G = (V, E), if for all pairs of nodes u,v, u can always reach v or v can always reach u , then we call this a Semiconnected graph. Now you are given a directed graph, you should tell us whether it is a Semiconnected graph. If it is, output “yes”, or else“no”.
There are several test cases, for each test case, there are two integers in the first line, n and m n(n<=10000) ,m(m<=50000) , means that there are n nodes and m edges in this graph. The nodes are numbered from 1 to n. Then m lines each with two integers u and v means there is an edge from u to v.
For each test case, output “yes” if it is a Semiconnected graph, or else “no” instead.
4 3
1 2
2 3
3 4
4 3
1 2
2 3
4 3
yes
no
题意:给你一个有向图,若从图中任意两个点u,v。都有从u到v的路径,或者从v到u的路径,则该图为半连通的,是则输出yes,不是则输出no
思路:若该图符合以上情况,
1:入度为0的点多于一个,不符合。
2:对该图进行缩点后,若为半连通图,则当前的图为一条直线,统计新图中入度,出度为0的点是不是都只有一个即可。
代码如下:
#include "stdio.h" //强连通缩点后,判断新图中入度为0,出度为0的点是否都只有一个 #include "string.h" #include "vector" #include "stack" using namespace std; #define N 10005 #define M 50005 struct node { int x,y; int next; }edge[M]; int idx,head[N]; void Init(){ idx=0; memset(head,-1,sizeof(head)); } void Add(int x,int y) { edge[idx].x=x; edge[idx].y=y; edge[idx].next=head[x]; head[x]=idx++; } int n; int dfs_clock; bool mark[N]; int scc_cnt; int belong[N]; stack<int> q; int num[N]; int low[N],dfn[N]; int MIN(int a,int b) { return a<b?a:b; } void DFS(int x) { int i,y; q.push(x); mark[x] = true; low[x] = dfn[x] = ++dfs_clock; for(i=head[x]; i!=-1; i=edge[i].next) { y=edge[i].y; if(!dfn[y]) { DFS(y); low[x] = MIN(low[x],low[y]); } else if(mark[y]) low[x] = MIN(dfn[y],low[x]); } if(low[x]==dfn[x]) { int temp; scc_cnt++; while(1) { temp = q.top(); q.pop(); belong[temp] = scc_cnt; num[scc_cnt]++; mark[temp] = false; if(temp==x) break; } } } int ru_du[N],chu_du[N]; void Solve(int id) { int i; int x,y; dfs_clock = scc_cnt = 0; memset(dfn,0,sizeof(dfn)); memset(num,0,sizeof(num)); memset(belong,0,sizeof(belong)); memset(mark,false,sizeof(mark)); DFS(id); for(i=1; i<=n; ++i) { if(!dfn[i]) DFS(i); } memset(ru_du,0,sizeof(ru_du)); memset(chu_du,0,sizeof(chu_du)); for(i=0; i<idx; ++i) { x = edge[i].x; y = edge[i].y; if(belong[x]!=belong[y]) { chu_du[belong[x]]++; ru_du[belong[y]]++; } } int ru_0=0; int chu_0=0; for(i=1; i<=scc_cnt; ++i) { if(ru_du[i]==0) ru_0++; if(chu_du[i]==0) chu_0++; } if(ru_0==1 && chu_0==1) printf("yes\n"); else printf("no\n"); } int ru[N],chu[N]; int main() { int i,m; int x,y; while(scanf("%d%d",&n,&m)!=EOF) { Init(); memset(ru,0,sizeof(ru)); memset(chu,0,sizeof(chu)); while(m--) { scanf("%d%d",&x,&y); Add(x,y); chu[x]++; ru[y]++; } int ans=0,id=1; for(i=1; i<=n; ++i) { if(ru[i]==0) { ans++; id=i; } } if(ans>1) { printf("no\n"); continue; } Solve(id); } return 0; }