zoukankan      html  css  js  c++  java
  • POJ

      1 /*
      2 POJ - 2438 哈密顿回路
      3 图的可行遍问题:一般就是哈密顿图和欧拉图
      4 这类问题,代码和算法本身简单,关键就在于建模。
      5 一般判断问题只要判断是否可行遍历!
      6 但是有的时候会有奇葩的要求:
      7 例如:遍历一张欧拉回路图:深度遍历不回溯法,o(n)
      8       遍历哈密顿回路:这道题
      9 言归正传:
     10 1、哈密顿图定义:从一个点出发、经过所有的点必须且只能一次,最终回到起点。图中有边可以不经过,但是不能经过两次。
     11 2、存在的充分条件:图有n个顶点,如果图中任意两个不同的顶点的度数之和大于等于n,则图是哈密顿图。
     12 3、遍历哈密顿图的算法:如下
     13 
     14 解题思路:
     15 1、题目是说,小朋友围一圈坐着,仇恨的不能坐在一起,让你安排座位。
     16 2、建图:可以连着坐的点连一条线,这道题就是求一个哈密顿的可行遍历。
     17 3、判断是否有解:因为每个人最多有n-1个敌人,然而有2*n个小朋友,满足上述充分条件,必然有解。
     18 
     19 */
     20 #include <iostream>
     21 #include <string.h>
     22 #include <stdio.h>
     23 #include <cmath>
     24 #include <vector>
     25 #define LL long long
     26 #define maxn 410
     27 using namespace std;
     28 
     29 bool map[maxn][maxn];
     30 int ans[maxn];
     31 inline void reverse(int s,int t){
     32     while(s<t){
     33         swap(ans[s],ans[t]);
     34         s++;t--;
     35     }
     36 }
     37 void Hamilton(int n){
     38     int s=1,t;
     39     int ansi=2;
     40     int w,i,j;
     41     bool visit[maxn]={false};
     42     for(i=1;i<=n;i++){
     43         if (map[s][i]) break;
     44     }
     45     t=i;
     46     visit[s]=visit[t]=true;
     47     ans[0]=s;
     48     ans[1]=t;
     49     while(1){
     50         while(1){
     51             for(i=1;i<=n;i++){
     52                 if (map[t][i] && !visit[i]){
     53                     ans[ansi++]=i;
     54                     visit[i]=true;
     55                     t=i;
     56                     break;
     57                 }
     58             }
     59             if (i>n) break;
     60         }
     61         w=ansi-1;
     62     i=0;reverse(i,w);
     63     swap(s,t);
     64     while(1){
     65         for(i=1;i<=n;i++){
     66             if (map[t][i] && !visit[i]){
     67                 ans[ansi++]=i;
     68                 visit[i]=true;
     69                 t=i;
     70                 break;
     71             }
     72         }
     73         if (i>n) break;
     74     }
     75     if (!map[s][t]){
     76         for(i=1;i<ansi-2;i++) if (map[ans[i]][t] && map[s][ans[i+1]]) break;
     77         w=ansi-1;
     78         i++;
     79         t=ans[i];
     80         reverse(i,w);
     81     }
     82     if (ansi==n) return ;
     83     for(j=1;j<=n;j++){
     84         if (visit[j]) continue;
     85         for(i=1;i<ansi-2;i++) if (map[ans[i]][j]) break;
     86         if (map[ans[i]][j]) break;
     87     }
     88     s=ans[i-1];
     89     t=j;
     90     reverse(0,i-1);
     91     reverse(i,ansi-1);
     92     ans[ansi++]=j;
     93     visit[j]=true;
     94     }
     95 }
     96 int n,m;
     97 int main(){
     98     while(cin>>n>>m){
     99         if (n==0 && m==0) break;
    100         memset(map,0,sizeof(map));
    101         for(int i=1;i<=m;i++){
    102             int u,v;
    103             scanf("%d%d",&u,&v);
    104             map[u][v]=map[v][u]=true;
    105         }
    106         for(int i=1;i<=2*n;i++){
    107             for(int j=1;j<=2*n;j++)
    108             if (i==j) continue;
    109             else map[i][j]=!map[i][j];
    110         }
    111         Hamilton(2*n);
    112         for(int i=0;i<2*n;i++)
    113         if (i!=2*n-1) printf("%d ",ans[i]);else printf("%d
    ",ans[i]);
    114     }
    115     return 0;
    116 }
  • 相关阅读:
    LF 第三章 装饰器和迭代器相关
    Python 文件管理
    Python 强制类型转换
    安装模块
    LF 第三章
    pep8 Python编码规则
    Help on module pyclbr:
    Help on class timedelta in module datetime:
    Help on function meshgrid in module numpy.lib.function_base:
    Help on module matplotlib.cm in matplotlib:
  • 原文地址:https://www.cnblogs.com/little-w/p/3614994.html
Copyright © 2011-2022 走看看