POJ 2762 Going from u to v or from v to u?

 #include<iostream>
using namespace std;
#define MAX 6010
typedef struct arc
{
 int adj;
 int next;
}arc;
struct EDGE
{
 int u,v;
}edge[MAX];
arc map[MAX];
arc rmap[MAX];
int p[MAX];
int rp[MAX];
int ts[MAX];
int sc[MAX];
int in[1100];
bool visit[1100];
bool graph[1100][1100];
int cnt,top;

void dfs1(int t)
{
 int k,q;
 visit[t]=true;
 q=p[t];
 while(q!=-1)
 {
        k=map[q].adj;
  if(!visit[k])
   dfs1(k);
  q=map[q].next;
 }
    ts[top++]=t;
}

void dfs2(int t)
{
 int q,k;
 visit[t]=true;
 sc[t]=cnt;
 q=rp[t];
 while(q!=-1)
 {
  k=rmap[q].adj;
  if(!visit[k])
   dfs2(k);
  q=rmap[q].next;
 }
}
bool Topusort(int n)
{
 int t=0,i,j,count=0;
 int degree[1100],stack[MAX];
 int sum=0;
 for(i=1;i<n;i++)
  degree[i]=0;
 for(i=1;i<n;i++)
 {
  for(j=1;j<n;j++)
   if(graph[i][j])
    degree[j]++;  
 }
 for(i=1;i<n;i++)
 {
  if(!degree[i])
  {
   stack[t++]=i;
   count++;
  }
 }
 if(count>1)
  return false;
 while(t)
 {
  sum=0;
  count++;
  i=stack[--t];
  for(j=1;j<n;j++)
  {
   if(graph[i][j])
    if(!(--degree[j]))
    {
     stack[t++]=j;
     sum++;
     if(sum>1)
      return false;
    }
  }
 }
 if(count<n)
  return false;
 else
  return true;
}
int main()
{
 int i,j=0,T;
 int n,m,u,v;
 scanf("%d",&T);
 while(T>0)
 {
  scanf("%d%d",&n,&m);
  memset(p,-1,sizeof(p));
  memset(rp,-1,sizeof(rp));
  memset(graph,false,sizeof(graph));
  memset(in,0,sizeof(in));
  for(i=1;i<=m;i++)
  {
   scanf("%d%d",&u,&v);
   map[i].next=p[u];
   map[i].adj=v;
   p[u]=i;
   edge[i].u=u;
   edge[i].v=v;
   
   rmap[i].next=rp[v];
   rmap[i].adj=u;
   rp[v]=i;
  }
  top=1;
  memset(visit,false,sizeof(visit));
  for(i=1;i<=n;i++)
  {
   if(!visit[i])
    dfs1(i);
  }
  cnt=1;
  memset(visit,false,sizeof(visit));
  for(i=n;i>=1;i--)
  {
   if(!visit[ts[i]])
   {
    dfs2(ts[i]);
    cnt++;
   }
  }
 // cout<<cnt<<endl;
  int k=cnt;
  for(i=1;i<=m;i++)
  {
   u=edge[i].u;
   v=edge[i].v;
   if(sc[u]!=sc[v])
   {
    graph[sc[u]][sc[v]]=true;
    in[sc[u]]++;
   }
  }
  cnt=0;
  for(i=1;i<k;i++)
  {
   if(!in[i])
    cnt++;
  }
  if(cnt>1)
   printf("No/n");
  else
  {
   if(Topusort(k))
    printf("Yes/n");
   else
    printf("No/n");
  }
  
  //system("pause");
  T--;
 }
 return 0;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值