Cod sursa(job #2560436)

Utilizator Rares31100Popa Rares Rares31100 Data 27 februarie 2020 23:34:41
Problema Ciclu hamiltonian de cost minim Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.42 kb
#include <bits/stdc++.h>
#define Inf 10000007

using namespace std;

ifstream in("fisier.in");
ofstream out("fisier.out");

int n,m,K;
int timp[31][31],ener[31][31];
bool ok[32][32];

struct bloc
{
    int Timp=Inf,Min=Inf,Left=0;
    int Lin,Col;
}a[31][31];
queue <bloc> c;
const int dLin[]={-1,-1,-1,0,1,1,1,0},dCol[]={-1,0,1,1,1,0,-1,-1};

int minim(int Min,int Left,int ener)
{
    if(ener<0)
        return max(Min,-ener);
    else if(ener<=Left)
        return Min;
    else
        return Min+(ener-Left);
}

int ramas(int Min,int Left,int ener)
{
    if(ener<0)
        return max(Min,-ener);
    else if(Left>=ener)
        return Left-ener;
    else
        return 0;
}

void citire()
{
    in>>n>>m>>K;

    for(int i=0;i<=n+1;i++)
        ok[i][0]=ok[i][m+1]=1;
    for(int j=0;j<=m+1;j++)
        ok[0][j]=ok[n+1][j]=1;

    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            in>>ener[i][j];

    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            in>>timp[i][j];

    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            a[i][j].Lin=i;
            a[i][j].Col=j;
        }
}

int main()
{
    citire();

    a[1][1].Timp=0;
    a[1][1].Min=ener[1][1];
    a[1][1].Left=ener[1][1];

    c.push(a[1][1]);

    while(!c.empty())
    {
        bloc nod=c.front();
        c.pop();

        for(int k=0;k<=7;k++)
            if(!ok[ nod.Lin+dLin[k] ][ nod.Col+dCol[k] ])
            {
                int i=nod.Lin+dLin[k];
                int j=nod.Col+dCol[k];

                if(a[i][j].Timp>nod.Timp+timp[i][j] && minim( nod.Min,nod.Left,ener[i][j] )<=K )
                {
                    a[i][j].Timp=nod.Timp+timp[i][j];
                    a[i][j].Min=minim( nod.Min,nod.Left,ener[i][j] );
                    a[i][j].Left=ramas( nod.Min,nod.Left,ener[i][j] );

                    c.push(a[i][j]);
                }
                else if( a[i][j].Timp==nod.Timp+timp[i][j] && a[i][j].Min>minim( nod.Min,nod.Left,ener[i][j] ) )
                {
                    a[i][j].Min=minim( nod.Min,nod.Left,ener[i][j] );
                    a[i][j].Left=ramas( nod.Min,nod.Left,ener[i][j] );

                    c.push(a[i][j]);
                }
            }
    }

    if(a[n][m].Timp!=Inf)
        out<<a[n][m].Timp<<'\n'<<a[n][m].Min;
    else
        out<<"Nu exista drum";

    return 0;
}