hdu 5215 Cycle(判断是否有奇数偶数的环)

13 篇文章 0 订阅

Cycle

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 179    Accepted Submission(s): 52


Problem Description
Ery is interested in graph theory, today he ask BrotherK a problem about it: Given you a undirected graph with  N  vertexes and  M  edges, you can select a vertex as your starting point, then you need to walk in the graph along edges. However, you can't pass a edge more than once, even opposite direction is forbidden. At the end, you should come back to the starting point. Assume you has passed  X  edges, there are two questions:

Question 1: Can  X  be a odd number ?

Question 2: Can  X  be a even number ?

(note: you must walk, so  X  can't be 0)
 

Input
The first line contains a single integer  T , indicating the number of test cases.

Each test case begins with two integer  N, M , indicating the number of vertexes and the number of edges. Following  M  lines, each line contains two integers  Ui, Vi , indicating there are a edge between vertex  Ui  and vertex  Vi .

T  is about 30

1  N  100000

0  M  300000

1  Ui,Vi  N

Ui  will not equal to  Vi

There is at most one edge between any pair of vertex.
 

Output
For each test, print two lines.

The first line contains "YES" or "NO" for question 1. 

The second line contains "YES" or "NO" for question 2.
 

Sample Input
  
  
3 1 0 3 3 1 2 2 3 3 1 4 4 1 2 2 3 3 4 4 1
 

Sample Output
  
  
NO NO YES NO NO YES
Hint
If you need a larger stack size, please use #pragma comment(linker, "/STACK:102400000,102400000") and submit your solution using C++.
 

n个顶点 m条无向边 问在这些边里面有没有一个环 里面有奇数条边 偶数条边

记录dfs过程中遍历点的深度 记录距离是偶数还是奇数

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string.h>
#include <string>
#include <vector>
#include <queue>

#define MEM(a,x) memset(a,x,sizeof a)
#define eps 1e-8
#define MOD 10009
#define MAXN 100010
#define MAXM 100010
#define INF 99999999
#define ll __int64
#define bug cout<<"here"<<endl
#define fread freopen("ceshi.txt","r",stdin)
#define fwrite freopen("out.txt","w",stdout)
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;

vector<int> vec[MAXN];
int dep[MAXN],vis[MAXN];
int ans[2];
int ji[MAXN];

void dfs(int x,int fa)
{
    vis[x]=1;
    int sz=vec[x].size();
    for(int i=0;i<sz;i++)
    {
        int y=vec[x][i];
        if(y==fa) continue;
        if(vis[y])
        {
            if(dep[x]>=dep[y])
            {
                int len=(dep[x]-dep[y]+1)&1;
                ans[len]++;
                if(len%2==1)
                {
                    ji[x]++;
                    if(ji[y]) ans[0]++;//两个都在奇数环里
                }
            }
            continue;
        }
        dep[y]=dep[x]+1;
        dfs(y,x);
    }
}

int main()
{
//    fread;
    int tc;
    scanf("%d",&tc);
    while(tc--)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        ans[0]=ans[1]=0;
        MEM(vis,0);  MEM(dep,0); MEM(ji,0);
        for(int i=0;i<=n;i++)
            vec[i].clear();
        for(int i=0;i<m;i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            vec[u].push_back(v);
            vec[v].push_back(u);
        }
        for(int i=1;i<=n;i++)
        {
            if(!vis[i])
                dfs(i,0);
        }
//        bug;
        if(ans[1])
            puts("YES");
        else puts("NO");
        if(ans[0])
            puts("YES");
        else puts("NO");
    }
    return 0;
}




评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值