Pagini recente » Cod sursa (job #2081607) | Cod sursa (job #1102967) | Cod sursa (job #1573308) | Cod sursa (job #1928564) | Cod sursa (job #2819821)
#include <iostream>
#include<fstream>
#include<vector>
#include<stack>
using namespace std;
ifstream f("ciclueuler.in");
ofstream g("ciclueuler.out");
vector<pair<int,int>> v[100005];
stack<int> s;
int grd[100005];
bool ok[100005], done[500025];//ok pt proprietatea de vizitat pt parcurgerea in adancime,
//done pt "stergerea" muchiilor pt eulerian
int N,M;
void dfs(int a)
{
ok[a]=true;
for(auto x: v[a])
{
if(ok[x.first]==false)
dfs(x.first);
}
}
//marcam nodul ca vizitat
// parcurgem vecinii nodului curent, daca acestia nu au fost vizitati,
//pornim un alt algoritm DFS, ne intoarcem de unde am plecat folosind recursivitatea
void euler(int a)
{
while(v[a].size()>0)//mai sunt muchii cu varful a
{
while(v[a].size()>0 and done[v[a].back().second]==true) //am trecut prin vecin scoatem muchia
v[a].pop_back();
if(v[a].size()>0)//inca muchii cu varful a
{
int urm=v[a].back().first, nr=v[a].back().second; //urm varf (back () pt ultimul element din vector)
done[nr]=true;//marcam indicele muchiei ca parcurs ca sa marcam ca muchia a fost parcursa
v[a].pop_back();//scoatem muchia
euler(urm);//facem recursiv pt urmatorul
}
}
s.push(a);
}
/*adăugăm pe stivă un vârf oarecare – de exemplu 1;
cât timp stiva nu este vidă
fie a – nodul din vârful stivei
determinăm nodurile x adiacente cu a.(icepem de la ultimul memorat in vector).Eliminăm muchia [a,x] și adăugăm nodul x pe stivă (apel recursiv)
continuăm cu nodul situat în vârful stivei
adăugăm nodul a în stiva, stiva construită reprezintă un ciclu eulerian*/
int main()
{
f>>N>>M;
//cin>>N>>M;
int x, y,nr=0;
for(int i=1;i<=M;i++)
{
nr++;
f>>x>>y;
//cin>>x>>y;
v[x].push_back({y,nr});
v[y].push_back({x,nr});
grd[x]++;//gradul lui x
grd[y]++;//gradul lui y
}
//for(auto x: v[1])
// cout<<x.first<<x.second;
//exemplu pt 4 4 1 2 1 3 2 4 3 4
// memoreaza v[1]= 2132 v[2]=1143 etc..
for(int i=1;i<=N;i++)
{
if(grd[i]%2==1)
{
g<<-1;
f.close();
g.close();
return 0;
}
}
//verficam eulerian, toate gradele trb sa fie pare,daca nu sunt pare atunci iesim din main prin return 0,gata
dfs(1); //parcurgere dfs
for(int i=1;i<=N;i++)
{
if(ok[i]==false)
{
g<<-1;
f.close();
g.close();
return 0;
}
}
//verificam ciclu eularian daca viziteaza toate muchiile din E,
//altfel nu e ciclu eulerian iesim din main prin return 0,gata
euler(1); //stim ca e eulerian, cautam un ciclu si il tinem in stiva
//afisam ciclul din stiva
while(!s.empty())
{
if(s.size()>=2)
g<<s.top()<<' ';
s.pop();
}
f.close();
g.close();
return 0;
}