Cod sursa(job #1104386)

Utilizator Juve45UAIC Alexandru Ionita Juve45 Data 10 februarie 2014 19:01:58
Problema Algoritmul lui Dijkstra Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.33 kb
#include <cstdio>
#include <vector>
#include <queue>

using namespace std;

#define pb push_back
#define dmax 987
#define x first
#define y second

int n;
short int m[dmax][dmax];
vector <int> v[dmax*dmax];
int maxm;
typedef pair <short int, short int> pi;
vector <pi> p;

int read()
{
   freopen("alpin.in", "r", stdin);
   freopen("alpin.out", "w", stdout);
    scanf("%i", &n);
    for(int i=0; i<n; i++)
        for(int ii=0; ii<n; ii++)
            scanf("%i", &m[i][ii]);
}

void make_graph()
{
    for(int i=0; i<n-1; i++)
        for(int ii=0; ii<n-1; ii++)
        {
            if(m[i][ii]<m[i][ii+1])
                v[i*n+ii].pb(i*n+ii+1);
            else
                if(m[i][ii]>m[i][ii+1])
                v[i*n+ii+1].pb(i*n+ii);

            if(m[i][ii]<m[i+1][ii])
                v[i*n+ii].pb((i+1)*n+ii);
            else
                if(m[i][ii]>m[i+1][ii])
                v[(i+1)*n+ii].pb(i*n+ii);
        }

    int i=n-1;
    for(int ii=0; ii<n-1; ii++)
    {
        if(m[i][ii]<m[i][ii+1])
            v[i*n+ii].pb(i*n+ii+1);
        else
            if(m[i][ii]>m[i][ii+1])
            v[i*n+ii+1].pb(i*n+ii);

    }
    int ii=n-1;
    for(int i=0;i<n-1;i++)
    {

            if(m[i][ii]<m[i+1][ii])
                v[i*n+ii].pb((i+1)*n+ii);
            else
                if(m[i][ii]>m[i+1][ii])
          v[(i+1)*n+ii].pb(i*n+ii);

    }

}

void toposort(int x)
{
    queue <int> q;
    q.push(x);
    m[x/n][x%n]=1;
    while(!q.empty())
    {
        x=q.front();
        q.pop();
        for(int i=0;i<v[x].size();i++)
        {
            if(m[v[x][i]/n][v[x][i]%n]<m[x/n][x%n]+1)
            {
                q.push(v[x][i]);

                m[v[x][i]/n][v[x][i]%n]=m[x/n][x%n]+1;
                if(m[v[x][i]/n][v[x][i]%n]>m[maxm/n][maxm%n])
                    maxm=v[x][i];
         }
        }
    }
}


void redefine_0()
{
    for(int i=0; i<=n; i++)
        for(int ii=0; ii<=n; ii++)
            m[i][ii]=0;

}

bool con(int a, int b)
{
    for(int i=0;i<v[a].size();i++)
    {
        if(v[a][i]==b)
            return true;
    }
    return false;
}


void way_back(int x)
{

    int val=m[x/n][x%n];

    int y = x%n;
    x=x/n;
    p.pb(make_pair(x+1,y+1));

    int dl[]= {1, 0, -1, 0};
    int dc[]= {0, 1, 0, -1};

    for(int i=val-1; i>0; i--)
    {
        for(int ii=0; ii<4; ii++)
        {
            if(m[x+dl[ii]][y+dc[ii]]==i && con((x+dl[ii])*n+y+dc[ii], x*n+y))
            {
                x=x+dl[ii];
                y=y+dc[ii];
                p.pb(make_pair(x+1,y+1));
                break;
            }
        }
    }

}

bool validate(int x)
{
    if(v[x].size()==4)
    return true;
    if(x/n==0 || x/n==n-1 || x%n==0 || x%n==n-1)
        if(v[x].size()==3)
        return true;
    if((x/n==0 || x/n==n-1) && (x%n==0 || x%n==n-1))
        if(v[x].size()==2)
        return true;
    return false;
}

void print_p()
{
    for(int i=p.size()-1;i>=0;i--)
        printf("%i %i\n", p[i].x, p[i].y);
}


int main()
{
    read();
    make_graph();
    redefine_0();
    for(int i=0; i<n*n; i++)
    {
        if(validate(i))
            toposort(i);
    }

    printf("%i\n", m[maxm/n][maxm%n]);

    way_back(maxm);

    print_p();
    return 0;
}