zoukankan      html  css  js  c++  java
  • ZOJ 3332 Strange Country II (竞赛图构造哈密顿通路)

    链接:http://www.icpc.moe/onlinejudge/showProblem.do?problemCode=3332

    本文链接:http://www.cnblogs.com/Ash-ly/p/5454611.html

    题意:

      给你一个N,代表含有N个点的竞赛图,接着的N * (N- 1) / 2行两个点u, v,代表存在有向边<u,v>,问是否能构造出来一个哈密顿通路.

    思路:

      竞赛图一定含有哈密顿通路,不一定含有哈密顿回路.则不可能出现不存在的情况,直接构造就可以,至于方法可看我的另外一篇文章:http://www.cnblogs.com/Ash-ly/p/5452580.html.

    注意:

      构造的时候从后往前寻找1或者0的时候一定是按照当前序列的顺序查找到,而不是按照点本身的顺序查找,在这里WA了几次.

    代码:

     1 #include <iostream>
     2 #include <cmath>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <cstdlib>
     6 #include <algorithm>
     7 #include <queue>
     8 #include <stack>
     9 #include <vector>
    10 
    11 using namespace std;
    12 typedef long long LL;
    13 const int maxN = 200;
    14 
    15 //The arv[] length is len, insert key befor arv[index] 
    16 inline void Insert(int arv[], int &len, int index, int key){ 
    17     if(index > len) index = len;
    18     len++;
    19     for(int i = len - 1; i >= 0; --i){
    20         if(i != index && i)arv[i] = arv[i - 1];
    21         else{arv[i] = key; return;}
    22     }
    23 }
    24 
    25 void Hamilton(int ans[maxN + 7], int map[maxN + 7][maxN + 7], int n){
    26     int ansi = 1;
    27     ans[ansi++] = 1;
    28     for(int i = 2; i <= n; i++){
    29         if(map[i][ans[ansi - 1]] == 1)
    30             ans[ansi++] = i;
    31         else{
    32             int flag = 0;
    33             for(int j = ansi - 2; j > 0; --j){//在当前序列中查找0/1
    34                 if(map[i][ans[j]] == 1){
    35                     flag = 1;
    36                     Insert(ans, ansi, j + 1, i);
    37                     break;
    38                 }
    39             }
    40             if(!flag)Insert(ans, ansi, 1, i);
    41         }
    42     }
    43 }
    44 
    45 int main()
    46 {
    47     //freopen("input.txt", "r", stdin);
    48     int t;
    49     scanf("%d", &t);
    50     while(t--){
    51         int N;
    52         scanf("%d", &N);
    53         int M = N * (N - 1) / 2;
    54         int map[maxN + 7][maxN + 7] = {0};
    55         for(int i = 0; i < M; i++){
    56             int u, v;
    57             scanf("%d%d", &u, &v);
    58             if(u < v)map[v][u] = 1;//建图,map[v][u] = 1,代表存在边<u, v>,且 u < v.
    59         }
    60         int ans[maxN + 7] = {0};
    61         Hamilton(ans, map, N);
    62         for(int i = 1; i <= N; i++)
    63             printf(i == 1 ? "%d":" %d", ans[i]);
    64         printf("
    ");
    65     }
    66     return 0;
    67 }

     代码2:

     1 #include <iostream>
     2 #include <cmath>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <cstdlib>
     6 #include <algorithm>
     7 #include <queue>
     8 #include <stack>
     9 #include <vector>
    10 
    11 using namespace std;
    12 typedef long long LL;
    13 const int maxN = 1000;
    14 
    15 inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
    17 
    18 void Hamilton(int ans[maxN + 7], int map[maxN + 7][maxN + 7], int n){
    19     int nxt[maxN + 7];//用数组模拟链表
    20     memset(nxt, -1, sizeof(nxt));
    21     int head = 1;
    22     for(int i = 2; i <= n; i++){
    23         if(map[i][head]){
    24             nxt[i] = head;
    25             head = i;
    26         }else{
    27             int pre = head, pos = nxt[head];
    28             while(pos != -1 && !map[i][pos]){
    29                 pre = pos;
    30                 pos = nxt[pre];
    31             }
    32             nxt[pre] = i;
    33             nxt[i] = pos;
    34         }
    35     }
    36     int cnt = 0;
    37     for(int i = head; i != -1; i = nxt[i])
    38         ans[++cnt] = i;
    39 }
    40 
    41 int main()
    42 {
    43     freopen("input.txt", "r", stdin);
    44     int N;
    45     while(~scanf("%d", &N)){
    46         int map[maxN + 7][maxN + 7] = {0};
    47         for(int i = 1; i <= N; i++){
    48             for(int j = 1; j <= N; j++){
    49                 int u;
    50                 read(u);
    51                 map[i][j] = u;
    52             }
    53         }
    54         printf("%d
    %d
    ", 1, N);
    55         int ans[maxN + 7] = {0};
    56         Hamilton(ans, map, N);
    57         for(int i = 1; i <= N; i++)
    58             printf(i == 1 ? "%d":" %d", ans[i]);
    59         printf("
    ");
    60     }
    61     return 0;
    62 }
  • 相关阅读:
    八皇后问题
    Catalan数与出栈顺序个数,Java编程模拟
    推荐系统中的协同过滤
    集成学习
    背包问题
    逆波兰表达式
    [leetcode]775. Global and Local Inversions
    [LeetCode]Minimum Moves to Equal Array Elements1,2
    链接属性
    常用表格属性
  • 原文地址:https://www.cnblogs.com/Ash-ly/p/5454611.html
Copyright © 2011-2022 走看看