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

来源:互联网 发布:跳跃网络是小公司吗 编辑:程序博客网 时间:2024/05/03 06:24

思路: 删除所有的有关点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 10002int 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 31 21 52 32 42 54 55 6 21 21 52 32 42 54 5*/