cCCF201512-4送貨

問題描述
  爲了增加公司收入,F公司新開設了物流業務。由於F公司在業界的良好口碑,物流業務一開通即受到了消費者的歡迎,物流業務馬上遍及了城市的每條街道。然而,F公司現在只安排了小明一個人負責所有街道的服務。
  任務雖然繁重,但是小明有足夠的信心,他拿到了城市的地圖,準備研究最好的方案。城市中有n個交叉路口,m條街道連接在這些交叉路口之間,每條街道的首尾都正好連接着一個交叉路口。除開街道的首尾端點,街道不會在其他位置與其他街道相交。每個交叉路口都至少連接着一條街道,有的交叉路口可能只連接着一條或兩條街道。
  小明希望設計一個方案,從編號爲1的交叉路口出發,每次必須沿街道去往街道另一端的路口,再從新的路口出發去往下一個路口,直到所有的街道都經過了正好一次。
輸入格式
  輸入的第一行包含兩個整數n, m,表示交叉路口的數量和街道的數量,交叉路口從1到n標號。
  接下來m行,每行兩個整數a, b,表示和標號爲a的交叉路口和標號爲b的交叉路口之間有一條街道,街道是雙向的,小明可以從任意一端走向另一端。兩個路口之間最多有一條街道。
輸出格式
  如果小明可以經過每條街道正好一次,則輸出一行包含m+1個整數p1, p2, p3, …, pm+1,表示小明經過的路口的順序,相鄰兩個整數之間用一個空格分隔。如果有多種方案滿足條件,則輸出字典序最小的一種方案,即首先保證p1最小,p1最小的前提下再保證p2最小,依此類推。
  如果不存在方案使得小明經過每條街道正好一次,則輸出一個整數-1。
樣例輸入
4 5
1 2
1 3
1 4
2 4
3 4
樣例輸出
1 2 4 1 3 4
樣例說明
  城市的地圖和小明的路徑如下圖所示。
p1
樣例輸入
4 6
1 2
1 3
1 4
2 4
3 4
2 3
樣例輸出
-1
樣例說明
  城市的地圖如下圖所示,不存在滿足條件的路徑。
p2
評測用例規模與約定
  前30%的評測用例滿足:1 ≤ n ≤ 10, n-1 ≤ m ≤ 20。
  前50%的評測用例滿足:1 ≤ n ≤ 100, n-1 ≤ m ≤ 10000。
  所有評測用例滿足:1 ≤ n ≤ 10000,n-1 ≤ m ≤ 100000。

/*
歐拉路徑 
1.判斷連通性,判斷結點度數(0個或2個結點度數爲奇數) 
2.若連通,其歐拉路徑 
*/ 
#include<iostream>
#include<fstream>
#include<vector>
#include<stack>
#include<algorithm>
#include<cstring>
#define N 10005 

using namespace std;

int n, m; 
stack <int> s;                  //DFS2棧 
vector <int> G[N];              //鄰接表 
int vis[N];                     //結點是否訪問 
bool map[N][N];                 //邊是否訪問 

//檢查圖的連通性 
void DFS1( int u ){
    vis[u] = 1;
    for( int i = 0; i < G[u].size(); i++ ){
        int v = G[u][i];
        if( vis[v] == 0 ){
            DFS1( v );
        }
    }
}

//求取歐拉路徑 
void DFS2( int u ){
    for( int i = 0; i < G[u].size(); i++ ){
        int v = G[u][i];
        if( !map[u][v] ){       //未訪問過的邊 
            map[u][v] = 1;
            map[v][u] = 1;
            DFS2( v );
            s.push( v );        //後處理,逆序push 
        }
    }
}

int main(){
    int a, b;               //標號爲a的交叉路口和標號爲b的交叉路口之間有一條街道
    int count = 0;          //度數爲奇數的結點個數 
    memset( G, 0, sizeof(G) );
    memset( vis, 0, sizeof(vis) );
    memset( map, 0, sizeof(map) );

//  ifstream fin("00.txt", ios::in);
    ifstream fin("01.txt", ios::in);
//  ifstream fin("02.txt", ios::in);
    fin >> n >> m;
//  cin >> n >> m;

    for( int i = 0; i < m; i++ ){
        fin >> a >> b;
//      cin >> a >> b;
        G[a].push_back(b);
        G[b].push_back(a);
    }

//  1.判斷圖的連通性 
    DFS1( 1 );
    for( int i = 1; i <= n; i++ ){
        if( vis[i] == 0 ){
            cout << -1;
            return 0;
        }
    }

//  2.判斷結點度數(0個或2個結點度數爲奇數)
    for( int i = 1; i <= n; i++ ){
        sort( G[i].begin(), G[i].end() );
        if( G[i].size() % 2 == 1 ){
            count++;
        }
    }
    if( count == 0 || count == 2 ){
        if( count == 2 && G[1].size() % 2 == 0 ){
                cout << -1;
                return 0;
        }
        DFS2( 1 );
    }else{
        cout << -1;
        return 0;
    }

    s.push( 1 );
    while( !s.empty() ){
        cout << s.top() << " ";
        s.pop();
    }

    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章