SGU 122 The book(哈密顿回路)

题意:每次给出与第i个点相邻的点,得到有向图后求哈密顿回路;

参考:http://blog.csdn.net/volzkzg/article/details/7514103

思路:由一点求相邻的链,构成环,再将不在环上的点加入环上,环上的点数为n时为哈密顿回路;

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <iostream>
using namespace std;
const int mn =1100;
int n,k,i,j,listNum;
int L[mn],R[mn],head,tail;
bool adj[mn][mn] ={0};
bool visit[mn];
string s;
void reverse(){//checked
    int tmp[mn],t = head,num=1;
    tmp[num]=head;
    while (t!=tail){
    t=R[t];tmp[++num]=t;
    }tmp[++num]=tail;
    if (adj[head][tail]){
    R[tail] = head;L[head] = tail;
    return ;
    }
    else for (int i=2;i<num-1;++i)
         if (adj[head][tmp[i+1]] && adj[tail][tmp[i]]){
         L[head] = R[head];R[head] = tmp[i+1];
         L[tmp[i+1]] = head;R[tail] = tmp[i];
         R[tmp[i]]=L[tmp[i]];L[tmp[i]] = tail;
         for (int j = i-1;j>=2;--j){
             int p = L[tmp[ j ]];
             L[tmp[ j ]] = R[tmp[ j ]];R[tmp[ j ]]=p;
         }
         return;
         }
}
void add(){
    int tmp[mn],t = head,num=1;
    tmp[num]=head;
    while (t!=tail){
    t=R[t];tmp[++num]=t;
    }tmp[++num]=tail;int pos;
    for (int i=1;i<=n;++i)
    if (visit[i]){pos = i;visit[i]=false;break;}
    for (int i =1;i<=num;++i)
    if (adj[tmp[i]][pos]){
        head = R[tmp[i]];tail = pos;
        R[tmp[i]] = pos;
        L[pos] = tmp[i];
        R[pos] = 0;
        listNum++;
        return;
    }
}
int findHead(){//checked
    for (int i=1;i<=n;++i)
    if (visit[i] && adj[head][i]){
        L[head] = i;R[i]=head;L[i]=0;visit[i]=false;
        return i;
    }
    return 0;
}
int findTail(){//checked
    for (int i=1;i<=n;++i)
    if (visit[i] && adj[tail][i]){
        R[tail] = i;L[i]=tail;R[i]=0;visit[i]=false;
        return i;
    }
    return 0;
}
void print(){
    int tmp[mn],t = 1,num=1;
    tmp[num]=1;
    while (R[t]!=1){
    t=R[t];tmp[++num]=t;
    }
    for (int i=1;i<=num;++i) cout << tmp[i] << " " ;
    cout << 1 << " " << endl;
}
void insert(){int v;//checked
    //左右两端进行不断的扩展
    while (v=findHead()) {head = v;listNum ++;}
    while (v=findTail()) {tail = v;listNum ++;}
    reverse();//Let哈密顿路成为哈密顿回路
    if (listNum == n) print();//如果回路中元素满足N个,那么输出
    else{
    int tmp = listNum;
    add();
    insert();
    }
}
void init(){//checked
    cin >> n;getchar();
    for (i = 1;i <= n;++i){
    getline(cin,s);k=0;
    for (int j=0;j<s.size();++j)
        if (s[j]!=‘ ‘) k=k*10+s[j]-‘0‘;
        else {adj[i][k]=true;k=0;}
    if (k!=0){
        adj[i][k]=true;k=0;
    }
    }memset(visit,true,sizeof(visit));
    tail = head = listNum = 1;visit[1]=false;
}
int main(){
    init();
    insert();
    return 0;
}  
时间: 2024-10-10 04:19:06

SGU 122 The book(哈密顿回路)的相关文章

The sum - SGU 122(斐波那契前N项和)

直接上代码....... ================================================================================================================ #include<stdio.h> const int MAXN = 41; int main() { long long Fib[MAXN] = {0, 1}, sum[MAXN]={0, 1}; for(int i=2; i<MAXN;

今日SGU 5.

SGU 122 题意:给你n个人,每个人有大于 N / 2(向上取整)的朋友,问你1这个人有一个书,每个人都想看,只能从朋友之间传递,然后最后回到了1这个人,问你 是否有解,然后有解输出路径 收获:哈密尔顿路 一:Dirac定理(充分条件) 设一个无向图中有N个顶点,若所有顶点的度数大于等于N/2,则哈密顿回路一定存在.(N/2指的是?N/2?,向上取整) 二:基本的必要条件 设图G=<V, E>是哈密顿图,则对于v的任意一个非空子集S,若以|S|表示S中元素的数目,G-S表示G中删除了S中的

SGU 438 The Glorious Karlutka River =) 拆点+动态流+最大流

The Glorious Karlutka River =) Time Limit:500MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Status Practice SGU 438 Appoint description: Description A group of Mtourists are walking along the Karlutka river. They want to cross

sgu Kalevich Strikes Back

这道题就是求一个大矩形被n个矩形划分成n+1个部分的面积,这些矩形之间不会相交,可能包含.. 1 #include <cstdio> 2 #include <cstring> 3 #include <vector> 4 #include <algorithm> 5 #define maxn 120100 6 using namespace std; 7 8 long long s[maxn]; 9 vector<int>g[maxn]; 10 i

数学计数原理(P&#243;lya,高精度):SGU 294 He&#39;s Circles

He's Circles He wrote n letters "X" and "E" in a circle. He thought that there were 2n possibilities to do it, because each letter may be either "X" or "E". But Qc noticed that some different sequences of letters ca

sgu Ice-cream Tycoon

题意:供应商提供n块价格为c的冰淇淋,一个学生想买n块冰淇淋,手中的钱数总共有t元,为了不让买n块冰淇淋所花费的钱数不超过t元,先尽可能卖给这个学生便宜的冰淇淋. 如果这个学生不能买到所需要的冰淇淋则输出“UNHAPPY”,能则输出“HAPPY”. 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define maxn 200000 5 using namespace std; 6 7

sgu 463 - Walking around Berhattan

K - Walking around Berhattan Time Limit:250MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice SGU 463 Description As you probably know, Berhattan is a district of Berland's largest city and it consists of equal squar

哈密顿回路算法详解

[转]哈密顿回路 原文链接:http://www.cnblogs.com/Ash-ly/p/5452580.html 概念: 哈密顿图:图G的一个回路,若它通过图的每一个节点一次,且仅一次,就是哈密顿回路.存在哈密顿回路的图就是哈密顿图.哈密顿图就是从一点出发,经过所有的必须且只能一次,最终回到起点的路径.图中有的边可以不经过,但是不会有边被经过两次. 与欧拉图的区别:欧拉图讨论的实际上是图上关于边的可行便利问题,而哈密顿图的要求与点有关. 判定: 一:Dirac定理(充分条件) 设一个无向图中

【SGU 390】Tickets (数位DP)

Tickets Description Conductor is quite a boring profession, as all you have to do is just to sell tickets to the passengers. So no wonder that once upon a time in a faraway galaxy one conductor decided to diversify this occupation. Now this conductor