hdu 5424 Rikka with Graph II

时间:2023-02-02 00:15:41

题解:
1.n点n边,如果图是联通的,那么就是一棵树上多一个边,导致树上出现一个环,这个环可能表现在自环,重边,真环上
2.考虑一条哈密顿路径,如果抛去多余的那一条边,那应该是从1度的起点一直走下去,到达1度的终点,经历的点都是两度的
3.无论多余的边如何加,哈密顿路起点的度一定不大于任何一点,那么我们选定这个点作为起点
4.dfs下去,如果有分叉点的时候,走度数相对低的点,经历的点数应该等于n
总结:
1.第一开始发现数据不大,无脑暴力了一下(枚举删边),后来看Stilwell大神的代码有了新的领悟
2.hdu 5424 Rikka with Graph II
第三种情况就需要找度数最小的点的去遍历来解决了
3.这道题也是WA了很多遍,解决的方法我觉得就是要理清思路,通过将所有的可能清楚地枚举在草稿纸上,由总体出发,慢慢细化
4.依旧是,如果WA了很多遍,一下子想不出来怎么做,就赶紧做一些别的事情,避免思维的禁锢

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<map>
#include<iterator>
using namespace std ;
typedef pair<int,int>pii;
#define MAXN 1005
int first[MAXN],d[MAXN],e,n,point,root = 1;
struct Edge
{
    int v,next;
}edge[MAXN << 1];
bool vis[MAXN];
void insert(int u,int v)
{
    edge[e].next = first[u];
    edge[e].v = v;
    first[u] = e++;
}
bool dfs(int u)
{
    point++;
    vis[u] = true;
    int v = -1;
    for(int i = first[u];i != -1;i = edge[i].next)if(!vis[edge[i].v])
        if(v == -1 || d[edge[i].v] < d[v])v = edge[i].v;
    if(v != -1)dfs(v);
    return point == n;
}
bool solve()
{
    memset(vis,0,sizeof(vis));
    point = 0;
    return dfs(root);
}
int main ()
{
    while(scanf("%d",&n) != EOF)
    {
        memset(first,-1,sizeof(first));
        e = 0;
        memset(d,0,sizeof(d));
        for(int i = 0;i < n;i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            d[u]++,d[v]++;
            insert(u,v);
            insert(v,u);
        }
        root = 1;
        for(int i = 1;i <= n;i++)
            if(d[root] > d[i])root = i;
        if(solve())puts("YES");
        else puts("NO");
    }
}