1. 程式人生 > >ccf 201512-4 送貨 無向圖歐拉回路

ccf 201512-4 送貨 無向圖歐拉回路

Problem:
n個節點m條路,看成一個無向圖,判斷能否每條路直走一次。
Solution:
先判斷度,只能是1個或2個奇數度。
然後判斷邊的數目是否等於m,否則是非連通圖。
然後按字典序最小遍歷即可,此時一定會有一條迴路。

#include <stdio.h>
#include <queue>

using namespace std;

const int max_v = 15;

int G[max_v][max_v];
int degree[max_v];
int n, start = 0, edge = 0;
queue<int> q;

bool
okDeg() {//只能有0個或2個點是奇數個度 int odd = 0; for (int i = 0; i < n; i++) { if(degree[i]%2 != 0) { odd++; if(start != 0) start = min(i, start); } if(odd > 2) return false; } if(odd == 1) return false; else
return true; } void dfs(int root) {//判斷無向圖的連通性 edge++; q.push(root); for(int i = 0; i < n; i++) { if(G[root][i]>0) { G[root][i] = G[i][root] = 0; dfs(i); } } } /* 4 6 1 2 1 3 1 4 2 4 3 4 2 3 */ int main() { // freopen("/Users/really/Documents/code/input","r",stdin);
memset(G, 0, sizeof(G)); int m; scanf("%d%d", &n, &m); for(int i = 0; i < m; i++) { int a, b; scanf("%d%d", &a, &b); G[a-1][b-1] = G[b-1][a-1] = 1; degree[a-1]++; degree[b-1]++; } if(!okDeg()) printf("-1\n"); else { dfs(start); if(edge-1 != m) printf("-1\n"); else { printf("%d", q.front()+1); q.pop(); while(!q.empty()) { printf(" %d", q.front()+1); q.pop(); } printf("\n"); } } return 0; }