sdut 2497 判断无向图所有环中是否都包括点S

思路: 删除所有的有关点S的边,然后判断剩余图中是否存在环!

/*判无向图是否含有环
 1.判断图中的结点数和边数
   <1>若n>=m,则输出提示有回路,并返回;
   <2>若n<m,继续往下执行;
2.结点入队
   遍历每个结点,若度数为1或0则入队,并记录下入队元素个数;
3.删除结点和边
在队列不为空的情况下,队头元素出队
   <1>若该结点度数为1,则置度数为-1,并且将与它相邻接的结点度数减1,同时判断减1后该邻接结点度数是否为1,若为1则入队,同时入队元素个数加1;
   <2>若该结点度数为0,则直接置度数为-1;
4. 判断有无回路
   <1>若入队元素个数小于结点总数,则有回路;
   <2>否则,无回路;
   */
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <queue>
using namespace std;
#define N 10002
int n, m,NE;
int v[N],head[N];
vector<int>g[N];
struct node
{
    int u,v,next;
}Edge[N*20];
void addEdge(int u,int v)
{
    Edge[NE].u=u,Edge[NE].v=v;
    Edge[NE].next=head[u];
    head[u]=NE++;
}
int main()
{
 int i, j, x, y,k, count,S;
 queue<int> q;
 while(scanf("%d%d%d",&n,&m,&S)!=EOF)
 {
  NE=k=0;
  memset(v,0,sizeof(v));
  memset(head,-1,sizeof(head));
  for(i = 1; i <= n; i++)
     g[i].clear();
  for(i=1;i<=m;i++)
  {
   scanf("%d %d",&x,&y);
   if(!(x==S||y==S))
   {
     addEdge(x,y);
     addEdge(y,x);
     v[x]++;
     v[y]++;
   }
  }
  while(!q.empty())
   q.pop();
  count = 0;
  for(i = 1; i <=n; i++)
  {
   if(v[i]<=1)
   {
    q.push(i);
    count++;
   }else k++;
  }
  while(!q.empty())
  {
   int u=q.front();
   q.pop();
   if(v[u] == 0)
    v[u] = -1;
   else if(v[u] == 1)
   {
    v[u] = -1;
    for(i=head[u];i!=-1;i=Edge[i].next)
    {
        int v1=Edge[i].v;
     if(v1!=u)
     {
      v[v1]--;
      if(v[v1] == 1)
      {
       q.push(v1);
       count++;
      }
     }
    }
   }
  }
  if(count<m-k)
   printf("NO\n");
  else
   printf("YES\n");
 }
 return 0;
}
/*
5 6 3
1 2
1 5
2 3
2 4
2 5
4 5
5 6 2
1 2
1 5
2 3
2 4
2 5
4 5
*/


你可能感兴趣的:(sdut 2497 判断无向图所有环中是否都包括点S)