Pagini recente » Cod sursa (job #3179822) | Cod sursa (job #1779502) | Cod sursa (job #161407) | Cod sursa (job #2915704) | Cod sursa (job #2961601)
#include <fstream>
#include <vector>
#include <queue>
using namespace std;
class Graph{
int n, m;
std::vector<std::vector<std::pair<int, int>>> graph;
std::vector<std::vector<int>> ctc;
std::vector<int> father;
std::vector<int> distance;
std::vector<int> lowlink;
std::vector<int> id;
std::vector<int> inDegree;
std::vector<int> outDegree;
std::vector<bool> visited;
std::stack<int> s;
int totalCost;
int index;
void dfs(const int k){
visited[k] = true;
for (const int node : getNeighbors(k)){
if ( !visited[node] ){
father[node] = k;
dfs(node);
}
}
s.push(k);
}
void bfs(const int start){
std::queue<int> q;
q.push(start);
visited[start] = true;
distance[start] = 0;
while (!q.empty()){
int node = q.front();
q.pop();
for (int neighbor : getNeighbors(node)){
if (!visited[neighbor]){
visited[neighbor] = true;
distance[neighbor] = distance[node] + 1;
father[neighbor] = node;
q.push(neighbor);
}
}
}
}
struct edge{
int cost, x, y;
bool operator<(const edge o) const{
return ((this->cost) > o.cost);
}
};
void dijkstra(const int start){
distance.assign(n+1, 0x7fffffff);
std::queue<std::pair<int, int>> q;
q.push({0, start});
distance[start] = 0;
while (!q.empty()){
int currentNode = q.front().second;
q.pop();
for (const auto &node : getNeighborsWithWeight(currentNode)){
if(distance[currentNode] + node.second < distance[node.first])
{
distance[node.first] = distance[currentNode] + node.second;
q.push({-distance[node.first], node.first});
}
}
}
}
void tarjan(int k){
visited[k] = true;
lowlink[k] = id[k] = index++;
s.push(k);
for (const int x : getNeighbors(k)){
if( !id[x] )
tarjan(x), lowlink[k] = std::min(lowlink[k], lowlink[x]);
else if( visited[x] )
lowlink[k] = std::min(lowlink[k], id[x]);
}
if(id[k] == lowlink[k]){
std::vector<int> tmp;
while(s.top() != k)
visited[s.top()] = false, tmp.push_back(s.top()) , s.pop();
visited[s.top()] = false, tmp.push_back(s.top()), s.pop();
ctc.push_back(tmp);
tmp.clear();
}
}
void topologicalSortFrom(const int start) {
visited.assign(n+1, false);
dfs(start);
}
public:
explicit Graph(const int n = 0){
this -> n = n;
index = totalCost = m = 0;
graph.resize(n+1);
father.resize(n+1);
distance.resize(n+1);
visited.resize(n+1);
lowlink.resize(n+1);
inDegree.resize(n+1, 0);
outDegree.resize(n+1, 0);
id.resize(n+1);
ctc.clear();
}
void addEdge(const int x, const int y, const int cost = 1){
graph[x].push_back({y, cost});
++inDegree[y];
++outDegree[x];
++m;
}
int getEdgeWeight(const int x, const int y) const {
for (const auto& neighbor : graph[x]) {
if (neighbor.first == y) {
return neighbor.second;
}
}
return (int)0x80000000;
}
std::vector<int> getNeighbors(const int x) const {
std::vector<int> neighbors;
for (const auto& neighbor : graph[x]) {
neighbors.push_back(neighbor.first);
}
return neighbors;
}
std::vector<std::pair<int, int>> getNeighborsWithWeight(const int x) const {
return graph[x];
}
std::vector<int> topologicalSort() {
visited.assign(n+1, false);
for (int i = 1; i <= n; ++i) {
if (!visited[i]) {
dfs(i);
}
}
std::vector<int> temp;
while ( !s.empty() ){
temp.push_back(s.top()), s.pop();
}
return temp;
}
void removeEdge(const int x, const int y){
for (auto it = graph[x].begin(); it != graph[x].end(); ++it) {
if (it -> first == y) {
graph[x].erase(it);
--m;
return;
}
}
}
void removeNode(const int x){
for (int i = 1; i <= n; ++i) {
removeEdge(i, x);
removeEdge(x, i);
}
graph[x].clear();
--n;
}
std::vector<std::pair<int, int>> MST(int x){
std::vector<std::pair<int, int>> mst;
visited.assign(n+1, false);
father.assign(n+1, 0);
visited[x] = true;
std::priority_queue<edge> q;
for(const auto &e : getNeighborsWithWeight(x)) {
edge V{e.second, x, e.first};
q.push(V);
}
while (!q.empty()){
edge k = q.top();
q.pop();
if(visited[k.y] == 0) {
mst.push_back({k.x, k.y});
father[k.y] = k.x;
totalCost += k.cost;
visited[k.y] = true;
for (const auto &e: getNeighborsWithWeight(k.y)){
edge V{e.second, k.y, e.first};
q.push(V);
}
}
}
return mst;
}
int getCost() const {
return totalCost;
}
int getShortestPathFromTo(const int from, const int to){
dijkstra(from);
return distance[to];
}
std::vector<int> getDistancesFrom(const int from){
dijkstra(from);
return distance;
}
int howManyCC(){
int count = 0;
visited.assign(n+1, false);
for (int i = 1; i <= n; ++i)
if(!visited[i]) {
dfs(i);
++count;
}
return count;
}
std::vector<std::vector<int>> CTC(){
lowlink.resize(n+1, 0);
id.resize(n+1, 0);
index = 1;
ctc.clear();
for (int i = 1; i <= n; ++i) {
if( !id[i] )
tarjan(i);
}
return ctc;
}
std::vector<int> DAG_distance(const int start){
topologicalSortFrom(start);
distance.assign(n+1, 0x7fffffff);
distance[start] = 0;
while ( !s.empty() ){
for(const auto &node : getNeighborsWithWeight(s.top())) {
if(distance[s.top()] + node.second < distance[node.first])
distance[node.first] = distance[s.top()] + node.second;
}
s.pop();
}
return distance;
}
std::vector<int> eulerianCycle(const int start){
std::vector<int> cycle;
while(!s.empty())
s.pop();
s.push(start);
while ( !s.empty() ){
int node = s.top();
if (!getNeighbors(node).empty()){
s.push(graph[node][0].first);
int k = graph[node][0].first;
removeEdge(k, node);
removeEdge(node, k);
}
else{
s.pop();
cycle.push_back(node);
}
}
return cycle;
}
std::vector<int> getFather() const {
return father;
}
int getInDegree(const int x) const {
return inDegree[x];
}
int getOutDegree(const int x) const {
return outDegree[x];
}
};
int main() {
ifstream in("ciclueuler.in");
int n, m;
in >> n >> m;
Graph g(n);
while(m--){
int x, y;
in >> x >> y;
g.addEdge(x, y);
g.addEdge(y, x);
}
in.close();
ofstream out("ciclueuler.out");
for (int i = 1; i <= n; ++i) {
if (g.getInDegree(i) % 2) {
out << "-1\n";
out.close();
return 0;
}
}
if(g.howManyCC() > 1) {
out << "-1\n";
out.close();
return 0;
}
std::vector<int> cycle = g.eulerianCycle(1);
for (int i = 0; i < cycle.size() - 1; ++i) {
out << cycle[i] << " ";
}
out.close();
return 0;
}