Cod sursa(job #1093078)

Utilizator valentin.harsanValentin Harsan valentin.harsan Data 27 ianuarie 2014 18:46:02
Problema Aho-Corasick Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.65 kb
#include<iostream>
#include<fstream>
#include<vector>
using namespace std;

const int N = 110;

int n, nr, o[N], m[N][N], smax;
vector<int> v[N], vt[N];
bool ver[N], ver2[N], ap[N];
vector<int> nod, rm;

void df1(int nod) {
    ver[nod] = 1;

    for(vector<int>::iterator it = v[nod].begin(); it != v[nod].end(); ++it) if(!ver[*it])
        df1(*it);
    o[++nr] = nod;
}

void df2(int nodd) {
    ver[nodd] = 1;
    nod.push_back(nodd);

    for(vector<int>::iterator it = vt[nodd].begin(); it != vt[nodd].end(); ++it) if(!ver[*it])
        df2(*it);
}

int grp[N], boss[N], start;

//1 : lant -> nod
//2 : nod -> lant
//3 : 1 + 2

void add(int nod) {
    int i;

    for(i = 1; i <= n; ++i) if(ap[i] && grp[i] != 3) {
        if(m[nod][i] && grp[i] == 2) {
            grp[i] = 3;
            continue;
        }
        if(m[nod][i]) {
            grp[i] = 1;
            continue;
        }

        if(grp[i] == 1) {
            grp[i] = 3;
            continue;
        }
        grp[i] = 2;
    }
}

int nu = 0, vvv = 1;

void df4(int nod) {
    add(nod);
    ++nu;
    ver[nod] = 1;

    for(vector<int>::iterator it = v[nod].begin(); it != v[nod].end(); ++it) if(ver2[*it]) {
        boss[nod] = *it;
        if(*it == start) {
            vvv = 0;
            break;
        }

        df4(*it);
        if(!vvv)
            break;
    }
}

void df3(int nod) {
    ver2[nod] = 1;

    for(vector<int>::iterator it = v[nod].begin(); it != v[nod].end(); ++it) if(ap[*it]) {
        if(ver2[*it]) {
            start = *it;
            df4(start);
            break;
        }

        df3(*it);
        if(start)
            break;
    }
}

void reconst() {
    int i, nc;

    //gaseste un ciclu

    df3(rm[1]);

    //$$$$$$$$$$$$$$$$$$$$$$

    while(nu != smax) {
        int vv = 0;

        for(i = 1; i <= n; ++i) if(!ver[i] && grp[i] == 3) {
            ++nu;
            vv = 1;
            ver[i] = 1;

            nc = start;
            while(!m[nc][i] || !m[i][boss[nc]])
                nc = boss[nc];

            boss[i] = boss[nc];
            boss[nc] = i;

            add(i);

            break;
        }

        if(vv)
            continue;

        for(i = 1; i <= n; ++i) if(!ver[i] && grp[i] == 1) {
            nu += 2;
            ver[i] = 1;

            for(int j = 1; j <= n; ++j) if(!ver[j] && grp[j] == 2 && m[i][j]) {
                ver[j] = 1;

                boss[j] = boss[start];
                boss[start] = i;
                boss[i] = j;

                add(j);

                break;
            }
            add(i);
        }
    }

    nc = start;
    do {
        cout << nc << " ";
        nc = boss[nc];
    } while(nc != start);
}

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

    cin >> n;

    for(i = 1; i <= n * (n + 1) / 2; ++i) {
        int a, b;
        cin >> a >> b;
        m[a][b] = 1;

        v[a].push_back(b);
        vt[b].push_back(a);
    }

    for(i = 1; i <= n; ++i) if(!ver[i])
        df1(i);

    for(i = 1; i <= n; ++i)
        ver[i] = 0;

    for(i = n; i; --i) if(!ver[i]) {
        nod.clear();

        df2(o[i]);

        if(nod.size() > smax) {
            smax = nod.size();
            rm = nod;
        }
    }

    for(i = 1; i <= n; ++i)
        ver[i] = 0;

    cout << smax << "\n";

    if(smax == 1) {
        cout << 1;
        return 0;
    }

    for(vector<int>::iterator it = rm.begin(); it != rm.end(); ++it)
        ap[*it] = 1;

    reconst();

    return 0;
}