Hamiltonish Path

原题:Hamiltonish Path

原题大意

给定一个无向图,有n个点,m条边,让你求出一条路径,这条路径有3个满足条件:

  • 这条路径至少穿过两个点
  • 这条路径只经过一个点一次
  • 任何与起点或终点相邻的点一定包括在这条路径里面

题目输入保证存在路径,并且多条路径时,输出任意一条

算法分析

可以从任意一点开始(记为x)。把x放到一个双端队列里,以之为起点。
然后重复执行一下内容:

  • 如果有与之相邻的点且不在队列里的,就将其放到队首,并以之为起点。
  • 如果有与队尾相邻(终点)且不在队列里,就将其放到队尾,并以之为终点。

直到队首队尾没有点与之相邻,或相邻的都在队列里,输出队列。

程序代码

#include <cstdio>
#include <vector>
#include <deque>
#include <memory.h>
#define mem(a,b) memset(a, b, sizeof(a))
using namespace std;
const int maxn = 1e5+5;
bool vis[maxn];
vector<int> vex;
vector<int> G[maxn];
deque<int> dq;
int n, m;
void Init(){
        mem(vis,0);
        vex.clear();
        dq.clear();
        for(int i = 0; i <= n; i++){
            G[i].clear();
        }
}
int main(){
    while(scanf("%d %d", &n, &m) != EOF){
        int x, y;
        Init();
        for(int i = 0; i < m; i++)
        {
            scanf("%d %d",&x, &y);
            G[x].push_back(y);
            G[y].push_back(x);
        }
        dq.push_back(1);
        vis[1] = true;
        bool fg = true, fg2 = true;
        while(fg || fg2){
            fg = false;
            int st = dq.front();
            for(int i = 0; i < G[st].size(); i++){
                if(!vis[G[st][i]])
                {
                    vis[G[st][i]] = true;   
                    dq.push_front(G[st][i]);
                    fg = true;
                    break;
                }
            }
            fg2 = false;
            int ed = dq.back();
            for(int i = 0; i < G[ed].size(); i++){
                if(!vis[G[ed][i]])
                {
                    vis[G[ed][i]] = true;   
                    dq.push_back(G[ed][i]);
                    fg2 = true;
                    break;
                }
            }

        }
        printf("%d\n", dq.size());
        while(!dq.empty()){
            printf("%d ", dq.front());
            dq.pop_front();
        }
        printf("\n");
    }
    return 0;
}