Pagini recente » Cod sursa (job #2451809) | Cod sursa (job #3030538) | Cod sursa (job #2591890) | Cod sursa (job #1920800) | Cod sursa (job #371814)
Cod sursa(job #371814)
#include <fstream>
#include <vector>
#include <stack>
#include <cstring>
#define MAXN 210
using namespace std;
ifstream fi("party.in");
ofstream fo("party.out");
int N,M;
vector<int> G[2][MAXN]; // G[0] - graf normal , G[1] - graf transpus
vector<int> GComp[MAXN]; // graful componentelor tare conexe
int WhatComp[MAXN],used[MAXN],NComps,usedComp[MAXN],assoc[MAXN],val[MAXN];
stack<int> S;
vector<vector<int> > Comps;
vector<int> sol;
//introducem in graf o restrictie de tipul x sau y
//N-x = ~x
void make_graph(int x, int y){
G[0][N-x+1].push_back(y);
G[1][y].push_back(N-x+1);
G[0][N-y+1].push_back(x);
G[1][x].push_back(N-y+1);
}
void afis(int i){
if ((i*2)<=N) fo<<i; else fo<<"~"<<N-i+1;
fo<<" ";
}
void get_input(){
int x,y,z;
fi>>N>>M;
N*=2;
for (int i=1;i<=M;++i){
fi>>x>>y>>z;
if (z==0) make_graph(x,y); else
if (z==1) make_graph(x,N-y+1); else
if (z==2) make_graph(N-x+1,y); else
make_graph(N-x+1,N-y+1);
}
fi.close();
}
//parcurgerea +
void DFSPlus(int nod,vector<int>* G){
used[nod]=1;
vector<int>::iterator it;
for (it=G[nod].begin();it!=G[nod].end();++it)
if (!used[*it]) DFSPlus(*it,G);
S.push(nod);
}
//parcurgerea -
void DFSMinus(int nod,vector<int>* G,int componenta){
WhatComp[nod]=componenta;
vector<int>::iterator it;
for (it=G[nod].begin();it!=G[nod].end();++it)
if (!WhatComp[*it]) DFSMinus(*it,G,componenta);
}
//sortare topologica
void topologica(int nod,vector<int>* G){
used[nod]=1;
vector<int>::iterator it;
for (it=G[nod].begin();it!=G[nod].end();++it)
if (!used[*it]) topologica(*it,G);
S.push(nod);
}
void get_output(){
fo<<sol.size()<<"\n";
for (vector<int>::iterator it=sol.begin();it!=sol.end();++it) fo<<(*it)<<"\n";
fo.close();
}
int main(){
get_input();
//determin componentele tare conexe
memset(used,0,sizeof(used));
memset(WhatComp,0,sizeof(WhatComp));
for (int i=1;i<=N;++i) if (!used[i]) DFSPlus(i,G[0]);
NComps=0;
while (!S.empty()){
if (!WhatComp[S.top()]){ ++NComps; DFSMinus(S.top(),G[1],NComps); }
S.pop();
}
Comps.resize(NComps+1);
for (int i=1;i<=N;++i) Comps[WhatComp[i]].push_back(i);
//construiesc DAG-ul componentelor tare conexe
for (int i=1;i<=N;++i){
memset(usedComp,0,sizeof(usedComp));
for (vector<int>::iterator it=G[0][i].begin();it!=G[0][i].end();++it)
if (WhatComp[i]!=WhatComp[*it] && !usedComp[WhatComp[*it]]){
GComp[WhatComp[i]].push_back(WhatComp[*it]);
usedComp[WhatComp[*it]]=1; // sa nu adaug acelasi vecin de 2 ori
}
}
for (int i=1;i<=N;++i) assoc[WhatComp[i]]=WhatComp[N-i+1]; // formez perechile de componente tare conexe
//sortez DAG-ul topologic
memset(used,0,sizeof(used));
for (int i=1;i<=NComps;++i)
if (!used[i]) topologica(i,GComp);
//caut solutia
memset(used,0,sizeof(used));
memset(val,0,sizeof(val));
while (!S.empty()){
if (!used[S.top()]){
for (vector<int>::iterator it=Comps[S.top()].begin();it!=Comps[S.top()].end();++it) { val[*it]=0;val[N-(*it)+1]=1; }
used[S.top()]=1;
used[assoc[S.top()]]=1;
}
S.pop();
}
for (int i=1;(i*2)<=N;++i)
if (val[i]) sol.push_back(i);
get_output();
return 0;
}