Cod sursa(job #1247915)

Utilizator ZenusTudor Costin Razvan Zenus Data 24 octombrie 2014 12:07:17
Problema Felinare Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.56 kb
#include <cstdio>
#include <vector>
#include <cstring>

using namespace std;

#define NMAX 9000

vector < int > G[NMAX];
bool marked[NMAX],left_marked[NMAX],right_marked[NMAX];
int left[NMAX],right[NMAX];
int stinse,N,M,X,Y,i;
bool flag;

bool can(int node)
{
    if (marked[node]) return false;
    marked[node]=true;

    vector < int > :: iterator u;

    for (u=G[node].begin();u!=G[node].end();++u)
    {
        if (right[*u]) continue;
        left[node]=*u;
        right[*u]=node;
        return true;
    }

    for (u=G[node].begin();u!=G[node].end();++u)
    {
        if (!can(right[*u])) continue;
        left[node]=*u;
        right[*u]=node;
        return true;
    }

    return false;
}

void df(int node)
{
    vector < int > :: iterator u;

    for (u=G[node].begin();u!=G[node].end();++u)
    {
        if (right_marked[*u]) continue;

        right_marked[*u]=true;
        left_marked[right[*u]]=false;
        df(right[*u]);
    }
}

int main()
{
freopen("felinare.in","r",stdin);
freopen("felinare.out","w",stdout);

for (scanf("%d%d",&N,&M);M;--M)
{
    scanf("%d%d",&X,&Y);
    G[X].push_back(Y);
}

flag=true;
while (flag)
{
    memset(marked,0,sizeof(marked));
    flag=false;

    for (i=1;i<=N;++i)
    if (!left[i]) flag|=can(i);
}

for (i=1;i<=N;++i)
if (left[i])
{
    ++stinse;
    left_marked[i]=true;
}

for (i=1;i<=N;++i)
if (!left_marked[i]) df(i);

for (i=1,printf("%d\n",2*N-stinse);i<=N;++i)
printf("%d\n",2*(1-right_marked[i])+1-left_marked[i]);

return 0;
}