Pagini recente » Cod sursa (job #430942) | Cod sursa (job #353920) | Cod sursa (job #2760890) | Cod sursa (job #2897849) | Cod sursa (job #1016805)
#include <fstream>
#include <algorithm>
#include <vector>
#include <stack>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <queue>
#define NM 210
using namespace std;
ifstream f("party.in");
ofstream g("party.out");
int N, M, K, C;
int X[NM], Y[NM], Z[NM];
int MinLevel[NM], Level[NM], Component[NM];
int In[NM], Out[NM];
int Simetric[NM], Value[NM];
vector<int> G[NM], NG[NM];
bool InStack[NM], E[NM][NM], Removed[NM];
stack<int> S;
queue<int> Q;
int Negate (int x)
{
return (x<=N?x+N:x-N);
}
void Build (int x, int y)
{
G[Negate(x)].push_back(y);
G[Negate(y)].push_back(x);
}
void Read ()
{
int x, y, z;
f >> N >> M;
for (int i=1; i<=M; i++)
{
f >> x >> y >> z;
X[i]=x; Y[i]=y; Z[i]=z;
if (z>1) x=Negate(x);
if (z%2) y=Negate(y);
Build(x, y);
}
C=M;
M=0;
f.close();
}
void DoTarjan (int node)
{
Level[node]=MinLevel[node]=++K;
S.push(node);
InStack[node]=1;
for (vector<int>::iterator it=G[node].begin(); it!=G[node].end(); ++it)
{
if (!Level[*it])
{
DoTarjan(*it);
MinLevel[node]=min(MinLevel[node], MinLevel[*it]);
continue;
}
if (InStack[*it])
MinLevel[node]=min(MinLevel[node], Level[*it]);
}
if (Level[node]==MinLevel[node])
{
++M;
int cnode;
do {
cnode=S.top();
InStack[S.top()]=0;
Component[S.top()]=M;
S.pop();
} while (cnode!=node);
}
}
void BuildComp ()
{
for (int i=1; i<=2*N; i++)
if (!Level[i])
DoTarjan(i);
for (int i=1; i<=2*N; i++)
{
Simetric[Component[i]]=Component[Negate(i)];
for (vector<int>::iterator it=G[i].begin(); it!=G[i].end(); ++it)
if (Component[i]!=Component[*it])
E[i][*it]=1;
}
for (int i=1; i<=M; i++)
for (int j=1; j<=M; j++)
if (E[i][j])
{
NG[i].push_back(j);
Out[i]++;
In[j]++;
}
}
void Solve ()
{
for (int i=1; i<=M; i++)
if (In[i]==0)
Q.push(i);
while (!Q.empty())
{
int node=Q.front();
Q.pop();
Removed[node]=1;
Removed[Simetric[node]]=1;
Value[node]=0;
Value[Simetric[node]]=1;
for (vector<int>::iterator it=NG[node].begin(); it!=NG[node].end(); ++it)
if (!Removed[*it])
{
--In[*it];
if (In[*it]<=0)
Q.push(*it);
}
}
}
int sol[NM];
bool isWrong (int i)
{
bool x=sol[X[i]], y=sol[Y[i]];
if (Z[i]>1) x=1-x;
if (Z[i]%2) y=1-y;
return !(x|y);
}
void Print ()
{
int ANS=0;
for (int i=1; i<=N; i++)
if (Value[Component[i]]==1)
sol[i]=1, ANS++;
else
sol[i]=0;
srand(time(0));
bool ok=0;
while (ok==0)
{
ok=1;
for (int i=1; i<=C; i++)
if (isWrong(i))
{
int x=X[i], y=Y[i];
if (rand()%2)
swap(x, y);
ANS-=sol[x];
sol[x]=1-sol[x];
ANS+=sol[x];
ok=0;
}
}
g << ANS << '\n';
for (int i=1; i<=N; i++)
if (sol[i]==1)
g << i << '\n';
g.close();
}
int main ()
{
Read();
BuildComp();
Solve();
Print();
return 0;
}