pku 2762Going from u to v or from v to u (求强连通分量+缩点+拓扑排序)
题目大意:给定有向图,任意给出两个点u、v,如果u到v有路或者v到u有路则输出Yes,否则输出No。
思路:求出强连通分量,然后缩点(建立新图),然后在这张新图中,拓扑排序一下,看拓扑排序是否唯一,如果唯一,则说明这个新图能构成一条最长的链,那么不是u到v有路,就是v到u有路了,输出Yes.
参考代码如下:
#include <stdio.h>
#include <string.h>
#define VN 1005
#define EN 6005
typedef struct ENode
{
int adv;
ENode *next;
} ENode;
ENode newnode[EN],newnode2[EN];
int newn,newn2;
typedef struct VNode
{
ENode *first;
} VNode;
VNode adjlist[VN],adjlist2[VN];
void insert(int i,int j)
{
ENode *p=newnode+newn++;
p->adv=j;
p->next=adjlist[i].first;
adjlist[i].first=p;
}
void insert2(int i,int j)
{
ENode *p=newnode2+newn2++;
p->adv=j;
p->next=adjlist2[i].first;
adjlist2[i].first=p;
}
int DFN[VN],LOW[VN],vcnt,belong[VN],bcnt,stack[VN],top;
bool instack[VN],indegree[VN];
void init(int n)
{
newn=0;
newn2=0;
memset(adjlist,0,n*sizeof(*adjlist));
memset(adjlist2,NULL,n*sizeof(*adjlist));
memset(DFN,0,4*n);
vcnt=0;
memset(belong,0,4*n);
bcnt=0;
top=-1;
memset(instack,false,n);
memset(indegree,false,n);
}
void tarjan(int u)
{
DFN[u]=LOW[u]=++vcnt;
stack[++top]=u;
instack[u]=true;
int v;
ENode *p=NULL;
for(p=adjlist[u].first; p ; p=p->next)
{
v=p->adv;
if(DFN[v]==0)
{
tarjan(v);
if(LOW[u]>LOW[v])
LOW[u]=LOW[v];
}
else if(instack[v] && LOW[u]>DFN[v])
LOW[u]=DFN[v];
}
if(LOW[u]==DFN[u])
{
bcnt++;
do
{
v=stack[top--];
instack[v]=false;
belong[v]=bcnt;
}
while(v!=u);
}
}
void display(int n)
{
ENode *p;
int i;
for(i=1; i<=n; i++)
{
printf("%d: ",i);
for(p=adjlist[i].first; p; p=p->next)
{
printf("%d ",p->adv);
}
printf("\n");
}
}
bool TopologicalSort()
{
ENode *p=NULL;
int i,index,num,end=1;
for(end=1; end<=bcnt; end++)
{
num=0;
for(i=1; i<=bcnt; i++)
{
if(indegree[i]==false)//缩点 入度为0
{
index=i;
num++;
}
}
if(num==0 || num>1) return false;
indegree[index]=true;
for(p=adjlist2[index].first; p; p=p->next)
indegree[p->adv]=false;
}
return true;
}
int main()
{
int test;
scanf("%d",&test);
while(test--)
{
int N,M,i,j;
scanf("%d %d",&N,&M);
init(N+1);
while(M--)
{
scanf("%d %d",&i,&j);
insert(i,j);
}
for(i=1; i<=N; i++)
if(DFN[i]==0)
tarjan(i);
ENode *p=NULL;
for(i=1; i<=N; i++)
{
for(p=adjlist[i].first; p; p=p->next)
{
j=p->adv;
if(belong[i]!=belong[j])
{
indegree[belong[j]]=true;
insert2(belong[i],belong[j]);
}
}
}
if(TopologicalSort())
printf("Yes\n");
else
printf("No\n");
}
return 0;
}
浙公网安备 33010602011771号