ccf 201512-4 送貨 無向圖歐拉回路
阿新 • • 發佈:2019-01-24
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;
}