Cod sursa(job #1379697)

Utilizator dan.seremetDan Seremet dan.seremet Data 6 martie 2015 19:01:41
Problema Ciclu Eulerian Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.85 kb
#include<fstream>
#include<vector>
#include<queue>
using namespace std;

ifstream u ("ciclueuler.in");
ofstream w ("ciclueuler.out");
//ofstream out_check ("check.out");

#define NMAX 100001
#define MMAX 500001
int nrnodes, nrarcs;
vector<int>G[NMAX];
vector<int> sol;
int grad[NMAX], viz[NMAX];

void initviz()
{for(int i=0; i<NMAX; i++)
	viz[i]=0;
}

void Read()
{u>>nrnodes>>nrarcs;
 int i, x, y;
 for(i=1; i<=nrarcs; i++)
	{u>>x>>y;
	 G[x].push_back(y);
	 grad[x]++;
     G[y].push_back(x);
     grad[y]++;
    }
}

void add_arc(int x, int y)
{G[x].push_back(y);
 G[y].push_back(x);
 grad[x]++; grad[y]++;
}

void remove_arc(int x, int y)
{vector<int>::iterator it;

 it=G[x].begin();
 while(it!=G[x].end() && *it!=y) it++;
 if(it!=G[x].end())
    {G[x].erase(it);
     grad[x]--;
    }

 it=G[y].begin();
 while(it!=G[y].end() && *it!=x) it++;
 if(it!=G[y].end())
    {G[y].erase(it);
     grad[y]--;
    }
}

//verifica daca toate nodurile au grad par
bool check_grad(int nrnodes)
{int i;
 for(i=1; i<=nrnodes; i++)
	if(grad[i]%2!=0) return 0;
 return 1;
}

//gaseste in cate noduri se poate ajunge din 'nod'
int DFScount(int nod)
{if(G[nod].empty()) return 1;

 viz[nod]=1;
 int S=G[nod].size(), c=1;
 for(int i=0; i<S; i++)
	{int nnod=G[nod][i];
	 if(!viz[nnod])
		c+=DFScount(nnod);
	}
 return c;
}

//face aceeasi chestie
int BFScount(int nod)
{if(G[nod].empty()) return 1;

 initviz();
 viz[nod]=1;
 int c=1, current, nextnod;
 queue<int> q;
 q.push(nod);
 while(!q.empty())
    {current=q.front();

     for(int i=0; i<G[current].size(); i++)
        {nextnod=G[current][i];
         if(!viz[nextnod])
         {
             c++;
             viz[nextnod]=1;
             q.push(nextnod);
         }
        }
     q.pop();
    }

 initviz();
 return c;
}

void printsol()
{int S=sol.size()-2;
 for(int i=0; i<=S; i++)
	w<<sol[i]<<" ";
 w<<"\n";
}

void euler(int current, int lvl)
{if(lvl>=sol.size()) sol.push_back(current);
 else sol.insert(sol.begin()+lvl, current);

 int S=G[current].size();
 int nod;
 while(G[current].size())
	{nod = G[current][0];
	 remove_arc(current, nod);
	 euler(nod, lvl+1);
	}
}

//debugging purposes
/*void afisaredecontrol()
{int i;
 for(i=1; i<=nrnodes; i++)
    {vector<int>::iterator it;
     out_check<<i<<": ";
     for(it=G[i].begin(); it!=G[i].end(); ++it)
        out_check<<*it<<" ";
     out_check<<"\n";
    }
 out_check<<"degree check: "<<check_grad(nrnodes)<<"\n";
 out_check<<"DFScount(1): "<<DFScount(1)<<"\n";
 out_check<<"BFScount(1): "<<BFScount(1)<<"\n";
}*/

int main()
{Read();
 initviz();

 //afisaredecontrol();

 if(check_grad(nrnodes))	//toate nodurile au grad par
	if(BFScount(1)==nrnodes) //Graful e conex
		{euler(1, 0);
		 printsol();
		}
    else w<<"-1";
 else w<<"-1";
 return 0;
}