hdu 5424 Rikka with Graph II (BestCoder Round #53 (div.2))(哈密顿通路判断)

http://acm.hdu.edu.cn/showproblem.php?pid=5424

哈密顿通路:联通的图,访问每个顶点的路径且只访问一次

n个点n条边

n个顶点有n - 1条边,最后一条边的连接情况:

(1)自环(这里不需要考虑);

(2)最后一条边将首和尾连接,这样每个点的度都为2;

(3)最后一条边将首和除尾之外的点连接或将尾和出尾之外的点连接,这样相应的首或尾的度最小,度为1;

(4)最后一条边将首和尾除外的两个点连接,这样就有两个点的度最小,度都为1

如果所给的图是联通的话,那么其度为1的点最多有2个,否则该图不连通

以度最小的点为起点进行DFS判断是否为哈密顿通路

 

哈密顿通路介绍:

https://en.wikipedia.org/wiki/Hamiltonian_path

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<algorithm>
#define N 1010
#define INF 0x3f3f3f3f

using namespace std;

int n, G[N][N], du[N], f;
bool vis[N];

void Init()
{
    memset(G, 0, sizeof(G));
    memset(du, 0, sizeof(du));//du[i]记录点i的入度
    memset(vis, false, sizeof(vis));
}

void DFS(int u, int cnt)
{
    int i;
    vis[u] = true;
    if(cnt == n)//访问次数与点的个数相等,则每个点都访问到了,且每个点只访问了一次
    {
        f = 1;
        return ;
    }
    for(i = 1 ; i <= n && !f ; i++)
    {
        if(!vis[i] && G[u][i])
        {
            DFS(i, cnt + 1);
            vis[i] = false;
        }
    }
}

int main()
{
    int u, v, i;
    while(~scanf("%d", &n))
    {
        Init();
        for(i = 1 ; i <= n ; i++)
        {
            scanf("%d%d", &u, &v);
            if(u != v && !G[u][v])//去除自环和重边的情况
            {
                G[u][v] = G[v][u] = 1;
                ++du[u];
                ++du[v];
            }
        }
        int s = 1, num = 0;//s记录度最小的点
        for(i = 1 ; i <= n ; i++)
        {
            if(du[i] == 1)
            {
                num++;//统计度为1的点的个数
                s = i;
            }
        }
        if(num > 2)
        {
            printf("NO\n");//判断其不连通,则不是哈密顿通路
            continue;
        }
        f = 0;
        DFS(s, 1);//从度最小的开始搜
        if(f == 1)
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}
View Code

 

posted @ 2015-08-31 17:45  午夜阳光~  阅读(160)  评论(0编辑  收藏  举报