Код:
#include <iostream>
#include <fstream>
#include <iomanip>
#include <vector>
using namespace std;
typedef short unsigned shun;
struct graph {
vector <vector <int> > adjNodes;
};
struct tour {
vector <int> u;
vector <int> v;
};
struct coords {
shun i;
shun j;
};
void FindEulerTour (graph& G, tour& T);
void FindEulerUtil (int u, graph& G, tour&);
bool IsValidNextEdge (int u, int v, graph& G);
void DFSCount (int index, graph& G, vector <bool>& used, int& count);
void RemoveEdge (int u, int v, graph& G);
coords RmEdge (int u, int v, graph& G);
void AddEdge (int u, int v, graph& G, coords&);
int main () {
shun numberOfNodes;
shun node;
fstream file;
file.open ("./data.in", ios::in);
file >> numberOfNodes;
graph Graph;
Graph.adjNodes.resize(numberOfNodes);
vector <shun> numberOfAdjNodes (numberOfNodes);
vector <vector <shun> > adjNodes;
for (shun i = 0; i < numberOfAdjNodes.size(); i++) {
file >> node;
file >> numberOfAdjNodes[node - 1];
vector <shun> tmp(numberOfAdjNodes);
for (shun j = 0; j < numberOfAdjNodes[node - 1]; j++) {
file >> tmp[j];
tmp[j]--;
Graph.adjNodes[i].push_back (tmp[j]);
}
}
numberOfAdjNodes.~vector();
file.close();
tour T;
FindEulerTour (Graph, T);
file.open ("./data.out", ios::out);
for (shun i = 0; i < T.u.size(); i++) {
file << setiosflags (ios::left) << setw(3) << T.u[i];
} file << endl;
for (shun j = 0; j < T.v.size(); j++) {
file << setiosflags (ios::left) << setw(3) << T.v[j];
} file << endl;
file.close();
system("PAUSE");
return 0;
}
void FindEulerTour (graph& G, tour& T) {
shun u = 0;
for (shun i = 0; i < G.adjNodes.size(); i++) {
if (G.adjNodes[i].size() & 1) {
u = i;
break;
}
}
FindEulerUtil(u, G, T);
}
void FindEulerUtil (int u, graph& G, tour& T) {
for (int v : G.adjNodes[u]) {
if (v != -1 && IsValidNextEdge (u, v, G)) {
T.u.push_back(u);
T.v.push_back(v);
RemoveEdge(u, v, G);
FindEulerUtil (v, G, T);
}
}
}
bool IsValidNextEdge (int u, int v, graph& G) {
shun count = 0;
for (int f : G.adjNodes[u]) {
if (f != -1) {
count++;
}
}
if (count == 1)
return true;
vector <bool> used (G.adjNodes.size());
for(shun i = 0; i < G.adjNodes.size(); i++) {
used[i] = false;
}
int count1 = 0;
DFSCount(u, G, used, count1);
coords uv = RmEdge(u, v, G);
for(shun i = 0; i < G.adjNodes.size(); i++) {
used[i] = false;
}
int count2 = 0;
DFSCount(u, G, used, count2);
AddEdge (u, v, G, uv);
return ((count1 > count2)? false: true);
}
void DFSCount (int index, graph& G, vector <bool>& used, int& count) {
used[index] = true;
for (int r : G.adjNodes[index]) {
if (r != -1 && !used[r]) {
count++;
DFSCount (r, G, used, count);
}
}
}
void RemoveEdge (int u, int v, graph& G) {
for (shun i = 0; i < G.adjNodes[u].size(); i++) {
if (G.adjNodes[u][i] == v) {
G.adjNodes[u][i] = -1;
break;
}
}
for (shun j = 0; j < G.adjNodes[v].size(); j++) {
if (G.adjNodes[v][j] == u) {
G.adjNodes[v][j] = -1;
break;
}
}
}
coords RmEdge (int u, int v, graph& G) {
coords uv;
for (uv.i = 0; uv.i < G.adjNodes[u].size(); uv.i++) {
if (G.adjNodes[u][uv.i] == v) {
G.adjNodes[u][uv.i] = -1;
break;
}
}
for (uv.j = 0; uv.j < G.adjNodes[v].size(); uv.j++) {
if (G.adjNodes[v][uv.j] == u) {
G.adjNodes[v][uv.j] = -1;
break;
}
}
return uv;
}
void AddEdge (int u, int v, graph& G, coords& uv) {
G.adjNodes[u][uv.i] = v;
G.adjNodes[v][uv.j] = u;
}