Pagini recente » Cod sursa (job #1219161) | Cod sursa (job #1132049)
#include<cstdio>
#include<vector>
using namespace std;
const int NMAX = 100+5;
const int MMAX = 1000+5;
void Read(),Solve(),Print();
int N,M,Top,NrCTC;
vector<int> V[2*NMAX]; // graful implicatiilor
#define V (V+NMAX)
vector<int> W[2*NMAX]; // graful transpus al implicatiilor
#define W (W+NMAX)
bool Viz[2*NMAX];
#define Viz (Viz+NMAX)
int TSort[2*NMAX];
int Comp[2*NMAX]; // Comp[i] spune in ce componenta tare-conexa se afla nodul i
#define Comp (Comp+NMAX)
int Opus[2*NMAX]; // Opus[i] spune care este componenta tare-conexa simetrica lui i
int Sol[NMAX];
vector<int> CTC[2*NMAX]; // CTC[i] contine nodurile din a i-a componenta tare-conexa
vector<int> G[2*NMAX]; // graful rezultat dupa contractarea componentelor tare-conexe
void SortareTopologica(int nod)
{
/* Sortare topologica a grafului initial */
vector<int>::iterator it;
Viz[nod]=1;
for(it=V[nod].begin(); it!=V[nod].end(); it++)
{
if(Viz[*it]) continue;
SortareTopologica(*it);
}
TSort[Top--]=nod;
}
void DFS(int nod)
{
/* DFS pe graful transpus al grafului initial */
vector<int>::iterator it;
Viz[nod]=0;
for(it=W[nod].begin(); it!=W[nod].end(); it++)
{
if(!Viz[*it]) continue;
DFS(*it);
}
CTC[Top].push_back(nod);
Comp[nod]=Top;
}
void ComponenteTareConexe()
{
int i,x;
Top=2*N;
for(i=-N; i<=N; i++)
{
if(!i) continue;
if(Viz[i]) continue;
SortareTopologica(i);
}
for(i=1; i<=2*N; i++)
{
x=TSort[i];
if(!Viz[x]) continue;
Top++;
DFS(x);
}
NrCTC=Top;
}
void ConstruiesteGraf()
{
/* Fiecare componenta tare-conexa se contracta
intr-un singur nod. */
int i,x;
vector<int>::iterator it,jt;
for(i=1; i<=NrCTC; i++)
{
for(it=CTC[i].begin(); it!=CTC[i].end(); it++)
{
x=*it;
for(jt=V[x].begin(); jt!=V[x].end(); jt++)
{
if(Comp[*jt]==i) continue;
G[i].push_back(Comp[*jt]);
}
}
}
for(i=1; i<=N; i++)
{
Opus[Comp[i]]=Comp[-i];
Opus[Comp[-i]]=Comp[i];
}
}
void SorteazaTopologic(int nod)
{
/* Sortare topologica a grafului contractat */
vector<int>::iterator it;
Viz[nod]=1;
for(it=G[nod].begin(); it!=G[nod].end(); it++)
{
if(Viz[*it]) continue;
SorteazaTopologic(*it);
}
TSort[Top--]=nod;
}
int main()
{
Read();
Solve();
Print();
return 0;
}
void Read()
{
int x,y,z;
freopen("party.in","r",stdin);
freopen("party.out","w",stdout);
scanf("%d%d",&N,&M);
for(; M; --M)
{
scanf("%d%d%d",&x,&y,&z);
if(z==1) y=-y;
else if(z==2) x=-x;
else if(z==3) x=-x,y=-y;
/* Construirea grafului de implicatii
x v y <=> (~x -> y) ^ (~y -> x) */
V[-x].push_back(y);
V[-y].push_back(x);
W[y].push_back(-x);
W[x].push_back(-y);
}
}
void Solve()
{
int i;
vector<int>::iterator it;
ComponenteTareConexe();
ConstruiesteGraf();
Top=NrCTC;
for(i=1; i<=NrCTC; i++)
{
if(Viz[i]) continue;
SorteazaTopologic(i);
}
for(i=1; i<=NrCTC; i++)
{
if(!Viz[i]) continue;
for(it=CTC[i].begin(); it!=CTC[i].end(); it++)
if(*it < 0) Sol[-(*it)]=1;
Viz[i]=0;
Viz[Opus[i]]=0;
}
}
void Print()
{
int i,ans=0;
for(i=1; i<=N; i++)
ans+=Sol[i];
printf("%d\n",ans);
for(i=1; i<=N; i++)
if(Sol[i]) printf("%d\n",i);
}