HDU 5424 Rikka with Graph II

题目大意: 在 N 个点 N 条边组成的图中判断是否存在汉密尔顿路径。

思路:忽略重边与自回路,先判断是否连通,否则输出“NO”,DFS搜索是否存在汉密尔顿路径。

  #include<iostream>
  #include<cstdio>
  #include<cstdlib>
  #include<cstring>
  #include<queue>
  #include<algorithm>
  #include<cmath>
  #include<map>
  #include<vector>
  using namespace std;
  #define INF 0x7fffffff
  int n,ans,vis[1010],f[1010],cnt;
  vector<int> adj[1010];
  #define pii pair<int,int>
  map<pii,int> MAP; 

  int find(int x){
      return f[x] == x ? x : f[x] = find(f[x]);
  }

  void init(){
      int i;
      for(i=0;i<=n;i++){
          adj[i].clear();
	   f[i] = i;
      }
  } 

  void judge(int u) {
      vis[u] = 1;
      cnt ++;
      int d = adj[u].size();
      for(int i = 0; i < d; i ++) {
             int v = adj[u][i];
             if(!vis[v]) {
              judge(v);
             }
      }
  }

  bool DFS(int u, int cnt) {
      vis[u] = 1;
      if(cnt == n) return true;
      int d = adj[u].size();
      for(int i = 0; i < d; i ++) {
          int v = adj[u][i];
          if(!vis[v]) {
              if(DFS(v, cnt + 1)) return true;
              vis[v] = 0;
          }
      }
      return false;
  }   


  int main(){
     int i,j,a,b,x,y,degree[1010];
     while(scanf("%d",&n) == 1){
	      memset(degree,0,sizeof(degree));
	      MAP.clear();
	      init();
	      for(i=1;i<=n;i++){
		      scanf("%d%d",&a,&b);
		      if(MAP.find(make_pair(a,b)) == MAP.end() && MAP.find(make_pair(b,a)) == MAP.end() && a != b){
			      degree[a] ++;
			      degree[b] ++; 
			      MAP[make_pair(a,b)] = 1;
			      MAP[make_pair(b,a)] = 1;
			      adj[a].push_back(b);
			      adj[b].push_back(a);
			      x = find(a);
			      y = find(b);
			      if(x != y)
				      f[x] = y;
		      }
	      }
	      int k,MIN = INF;
	      for(i=1;i<=n;i++)
	          if(degree[i] < MIN){
	    	      k = i;
	    	      MIN = degree[i];
	          }
	      int num2 = 0;
	      for(i=1;i<=n;i++){
		      if(degree[i] == 1)
		          num2 ++;
	      }
	      if(num2 > 2){
		      printf("NO
");
		      continue ;
	      }
	
	      cnt = 0;
	      memset(vis,0,sizeof(vis));
	      judge(1);
	      if(cnt != n){
		      printf("NO
");
	              continue;
	      }		
	      memset(vis,0,sizeof(vis));
	      if(DFS(k,1))
	          printf("YES
");
	      else
	          printf("NO
");
            }
      return 0;
  }
原文地址:https://www.cnblogs.com/jxgapyw/p/4771119.html