Pagini recente » Cod sursa (job #536462) | Cod sursa (job #388925) | Cod sursa (job #373513) | Cod sursa (job #2400033) | Cod sursa (job #610230)
Cod sursa(job #610230)
#include <fstream>
#include <iostream>
#include <vector>
#include <stack>
#include <list>
#include <string.h>
#define MAXN 100001
using namespace std;
typedef unsigned int uint32;
struct Edge
{
Edge()
{}
Edge(const int s,
const int d) : src(s), dest(d)
{}
int src, dest;
list<list<Edge>::iterator>::iterator node1, node2;
};
list<Edge> Edges;
typedef vector< list<list<Edge>::iterator> > Graph;
list<int> VerticesWithUnusedEdges;
list<int>::iterator VerticesWithUnusedEdgesIndexes[MAXN];
int EulerCycle(Graph& graph,
list<Edge>& Edges,
list<int>& VerticesWithUnusedEdges,
list<int>::iterator *VerticesWithUnusedEdgesIndexes,
list<int>& finalCycle)
{
list<int>::iterator finIt, finItNext;
finIt = finalCycle.begin();
finItNext = finalCycle.end();
VerticesWithUnusedEdges.push_front(0);
VerticesWithUnusedEdgesIndexes[0] = VerticesWithUnusedEdges.begin();
while (!VerticesWithUnusedEdges.empty() && !Edges.empty())
{
int start;
int node;
list<int> currentCycle;
start = VerticesWithUnusedEdges.front();
node = start;
currentCycle.push_back(start);
//cout << "Start = " << start+1 << "\n";
do
{
list<list<Edge>::iterator>::iterator it=graph[node].begin();
//cout << "Processing node: " << (*it)->src+1 << "\n";
//cout << "Processing edge: " << (*it)->src+1 << " " << (*it)->dest+1 << "\n" << "\n";
graph[(*it)->src].erase((*it)->node1);
if (graph[(*it)->src].empty() && VerticesWithUnusedEdgesIndexes[(*it)->src]!=VerticesWithUnusedEdges.end())
{
//cout << "Erasing " << (*it)->src+1 << "\n";
VerticesWithUnusedEdges.erase(VerticesWithUnusedEdgesIndexes[(*it)->src]);
}
if ((*it)->src != (*it)->dest)
{
graph[(*it)->dest].erase((*it)->node2);
if (graph[(*it)->dest].empty() && VerticesWithUnusedEdgesIndexes[(*it)->dest]!=VerticesWithUnusedEdges.end())
{
//cout << "Erasing " << (*it)->dest+1 << "\n";
VerticesWithUnusedEdges.erase(VerticesWithUnusedEdgesIndexes[(*it)->dest]);
}
}
if (node == (*it)->src)
node = (*it)->dest;
else
node = (*it)->src;
Edges.erase((*it));
if (node != start)
currentCycle.push_back(node);
else
break;
} while(!Edges.empty());
if (!finalCycle.empty())
{
if (*finIt == *currentCycle.begin())
finalCycle.splice(finIt, currentCycle, currentCycle.begin(), currentCycle.end());
else
finalCycle.splice(finItNext, currentCycle, currentCycle.begin(), currentCycle.end());
}
else
{
finalCycle.splice(finIt, currentCycle, currentCycle.begin(), currentCycle.end());
}
for (list<int>::iterator it=finalCycle.begin(); it!=finalCycle.end(); ++it)
{
list<int>::iterator auxIt = it;
auxIt++;
if (!graph[*it].empty())
{
finIt = it;
finItNext = auxIt;
VerticesWithUnusedEdges.push_front(*it);
VerticesWithUnusedEdgesIndexes[*it] = VerticesWithUnusedEdges.begin();
}
}
}
return 0;
}
int main()
{
int n,m;
int *degree;
Graph graph;
list<int> path;
fstream fin("ciclueuler.in", fstream::in);
fstream fout("ciclueuler.out", fstream::out);
fin >> n >> m;
//cout << n << " " << m << "\n";
degree = new int[n+1];
memset(degree, 0, (n+1)*sizeof(int));
graph.resize(n);
for (int i=0; i<m; ++i)
{
int x,y;
fin >> x >> y;
Edges.push_front(Edge(x-1,y-1));
graph[x-1].push_front(Edges.begin());
Edges.begin()->node1 = graph[x-1].begin();
if (x != y)
{
graph[y-1].push_front(Edges.begin());
Edges.begin()->node2 = graph[y-1].begin();
}
degree[x-1]++;
degree[y-1]++;
}
for (int i=0; i<n; ++i)
{
if (degree[i]%2)
{
//cout << i+1 << " has degree " << degree[i] << "\n";
fout << -1 << "\n";
goto done_label;
}
}
for (int i=n-1; i>=0; --i)
{
//VerticesWithUnusedEdges.push_front(i);
VerticesWithUnusedEdgesIndexes[i] = VerticesWithUnusedEdges.end();
}
/*for (list<int>::iterator it=VerticesWithUnusedEdges.begin(); it!=VerticesWithUnusedEdges.end(); ++it)
{
cout << *it+1 << " ";
}
cout << "\n";
VerticesWithUnusedEdges.erase(VerticesWithUnusedEdgesIndexes[2]);
for (list<int>::iterator it=VerticesWithUnusedEdges.begin(); it!=VerticesWithUnusedEdges.end(); ++it)
{
cout << *it+1 << " ";
}
cout << "\n";*/
/*for (list<Edge>::iterator it=Edges.begin(); it!=Edges.end(); ++it)
{
cout << "(" << it->src+1 << "," << it->dest+1 << ") ";
}
cout << "\n";*/
EulerCycle(graph, Edges, VerticesWithUnusedEdges, VerticesWithUnusedEdgesIndexes, path);
if (Edges.empty())
{
for (list<int>::iterator it=path.begin(); it!=path.end(); ++it)
fout << *it+1 << " ";
fout << "\n";
}
else
{
//cout << "Graph isn't connex so fail\n";
fout << -1 << "\n";
}
/*for (int i=0; i<n; ++i)
{
cout << i+1 << ": ";
for (list<list<Edge>::iterator>::iterator it=graph[i].begin(); it!=graph[i].end(); ++it)
{
cout << "(" << (*it)->src+1 << " " << (*it)->dest+1 << ") ";
}
cout << "\n";
}
{
list<Edge>::iterator it=Edges.begin();
for (int i=0; i<3; ++i)
it++;
graph[it->src].erase(it->node1);
if (it->src != it->dest)
graph[it->dest].erase(it->node2);
Edges.erase(it);
}
cout << "\n";
for (int i=0; i<n; ++i)
{
cout << i+1 << ": ";
for (list<list<Edge>::iterator>::iterator it=graph[i].begin(); it!=graph[i].end(); ++it)
{
cout << "(" << (*it)->src+1 << " " << (*it)->dest+1 << ") ";
}
cout << "\n";
}*/
done_label:
delete[] degree;
fin.close();
fout.close();
return 0;
}