考察算法 图的强连通分量。
题目的意思就不说了。就是看告诉你的图能否强连通,是所有结点。
我用的是Tarjan算法。
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
const int eMaxsize = 100050;
const int vMaxsize = 10005;
typedef struct/*边表存储*/
{
int next,s,e;
} node;
node edge[eMaxsize];
int head[vMaxsize],num_edge,dfn[vMaxsize],low[vMaxsize],index;
int cnt;
bool vis[vMaxsize];
void addedge(int a,int b)/*加边函数*/
{
edge[num_edge].s = a;
edge[num_edge].e = b;
edge[num_edge].next = head[a];
head[a] = num_edge++;
}
void getmap(int n,int m)/*建图*/
{
int a,b;
memset(head,-1,sizeof(head));
memset(vis,false,sizeof(vis));
memset(dfn,-1,sizeof(dfn));
memset(low,0,sizeof(low));
num_edge = 0;
while(m--)
{
scanf("%d %d",&a,&b);
addedge(a,b);
}
}
stack<int>s;
void Tarjan(int u)/*求强连通分量算法*/
{
dfn[u] = low[u] = ++index;
vis[u] = true;
s.push(u);
for(int i = head[u] ; i!=-1 ; i = edge[i].next)
{
int v = edge[i].e;
if(dfn[v] == -1)
{
Tarjan(v);
if(low[u] > low[v])
{
low[u] = low[v];
}
}
else if(vis[v] && low[u] > dfn[v])
{
low[u] = dfn[v];
}
}
if(low[u] == dfn[u])
{
int j;
cnt++;/*确定强连通分量的个数*/
do
{
j = s.top();
s.pop();
vis[j] = false;
}while(j!=u);
}
}
void solve(int n)
{
int i;
index = cnt = 0;
for(i = 1; i <= n ; i++)
{
if(dfn[i] == -1)
{
Tarjan(i);
}
}
if(cnt == 1)
{
printf("Yes\n",cnt);
}
else
{
printf("No\n",cnt);
}
}
int main()
{
int n,m;
while(scanf("%d %d",&n,&m) && n+m)
{
getmap(n,m);
solve(n);
}
return 0;
}