BestCoder Round #53 (div.2)1003 Rikka with Graph II 哈密顿路径 dfs

Rikka with Graph II

 
 Accepts: 27
 
 Submissions: 614
 Time Limit: 2000/1000 MS (Java/Others)
 
 Memory Limit: 65536/65536 K (Java/Others)
问题描述
众所周知,萌萌哒六花不擅长数学,所以勇太给了她一些数学问题做练习,其中有一道是这样的:

勇太有一张nn个点nn条边的无向图,现在他想要知道这张图是否存在一条哈密顿路径。

当然,这个问题对于萌萌哒六花来说实在是太难了,你可以帮帮她吗?
输入描述
数据组数不超过100组。每组数据的第一行一个整数n(1 \leq n \leq 1000)n(1n1000)。

接下来nn行。每行两个整数u,v(1 \leq u,v \leq n)u,v(1u,vn),代表给定图上的一条边。
输出描述
对于每一组数据,如果图中存在一条哈密顿路径,输出"YES"否则输出"NO"。
输入样例
4
1 1
1 2
2 3
2 4
3
1 2
2 3
3 1
输出样例
NO
YES
Hint
第二组数据的一条哈密顿路径是1->2->3

如果你不知道哈密顿路径是什么,戳这里(https://en.wikipedia.org/wiki/Hamiltonian_path).

当时没接触过哈密顿路径,想了想是dfs

,当时以为起点是1,终点是n,结果就开始判断度数,起点和终点的,

后来wa了几发次发现,起点和终点任意选,然后开始进行n次dfs,

当时大脑晕啊晕的,一直认为会超时,还认为没了起点和终点度数判断就没用了,结果都给去了,

后来T啊T的,哭,别赛完了,看别人AC的代码,尼玛就是比我多了个度数判断,

而且我还发现点数=n,边数也=n,原来点的数量=边的数量,尼玛,这么重要的条件比赛的时候我却没发现哭

我想了想,度数判断还是可以的,只要有超过两个点的度数<2,那一定不存在哈密顿路径。

而且哭我还发现,时间复杂度是O(n*(n+n)),n最大1000,尼玛,这哪门子的会超时,我靠!!!哭


然后在hdu上一交立马过了,哭哭哭



<span style="font-size:18px;">#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<climits>
#include<queue>
#include<vector>
#include<map>
#include<sstream>
#include<set>
#include<stack>
#include<utility>
#pragma comment(linker, "/STACK:102400000,102400000")
#define PI 3.1415926535897932384626
#define eps 1e-10
#define sqr(x) ((x)*(x))
#define FOR0(i,n)  for(int i=0 ;i<(n) ;i++)
#define FOR1(i,n)  for(int i=1 ;i<=(n) ;i++)
#define FORD(i,n)  for(int i=(n) ;i>=0 ;i--)
#define  lson   num<<1,le,mid
#define rson    num<<1|1,mid+1,ri
#define MID   int mid=(le+ri)>>1
#define zero(x)((x>0? x:-x)<1e-15)
#define mk    make_pair
#define _f     first
#define _s     second

using namespace std;
const int INF =0x3f3f3f3f;
const int maxn= 1000+10   ;
//const int maxm=    ;
//const int INF=    ;
typedef long long ll;
//const ll inf =1000000000000000;//1e15;
//ifstream fin("input.txt");
//ofstream fout("output.txt");
//fin.close();
//fout.close();
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
//by yskysker123
int n;

bool ok;
bool vis[maxn];
int in[maxn];
vector<int >  G[maxn];
void dfs(int x,int num )
{
    if( num==n)
    {

       ok=1;

       return ;
      }
    if(ok)  return;
    for(int i=0;i<G[x].size()&&!ok;i++)
    {
        int y=G[x][i];
        if(vis[y])  continue;
        vis[y]=1;
        dfs(y,num+1);
        vis[y]=0;
    }



}
int main()
{
    while(~scanf("%d",&n))
    {
        int x,y;
        memset(in,0,sizeof in);
        for(int i=1;i<=n;i++)
        {
            G[i].clear();
        }
        FOR1(i,n)
        {
            scanf("%d%d",&x,&y);
            G[x].push_back(y);
            G[y].push_back(x);
            in[x]++;in[y]++;
        }


      int cnt=0;
      for(int i=1;i<=n;i++)
      {
          if(in[i]<2)  cnt++;
      }
      if(cnt>2)  {puts("NO");continue;}

       ok=0;
    for(int i=1;i<=n&&!ok;i++)
    {
         memset(vis,0,sizeof vis);
       vis[i]=1;
       dfs(i,1);
    }





       puts(ok?"YES":"NO");

    }


    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值