Cod sursa(job #1648139)

Utilizator rughibemBelcineanu Alexandru Ioan rughibem Data 11 martie 2016 02:25:01
Problema Salvare Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.81 kb
#include<stdio.h>
#include<algorithm>
#include<vector>
#define DIM 1005
FILE *f=fopen("salvare.in","r"), *g=fopen("salvare.out","w");

using namespace std;

vector <int> v[DIM];

int N, K, INF = DIM;
int Grad[DIM], Grad2[DIM], viz[DIM], DMax[DIM], SOL[DIM];

void Citire(){
int i, X, Y;

    fscanf(f,"%d\n%d\n",&N,&K);

    for(i=1;i<=N-1;i++){

        fscanf(f,"%d %d\n",&X,&Y);

        v[X].push_back(Y);
        v[Y].push_back(X);

        Grad2[X] ++;
        Grad2[Y] ++;

    }

}

void Initializari(){
int i;

    for(i=1;i<=N;i++){
        Grad[i] = Grad2[i];
        DMax[i] = INF;
        SOL[i] = 0;
        viz[i] = 0;
    }

}

bool Verif( int M ){
int i, Q[DIM], Qst, Qfn, NOD, newNOD, nrSALVARI = 0, ok, nrfv = 0;

    Initializari();

    Qst = 1;
    Qfn = 0;
    for(i=1;i<=N;i++)
        if( Grad[i] == 1 ){
            Q[ ++Qfn ] = i;
            viz[i] = 1;
            DMax[i] = M;
        }

    while( Qst <= Qfn ){

        NOD = Q[Qst];

        ok = 0;
        for(i=0;i<v[NOD].size();i++){

            newNOD = v[NOD][i];

            if( viz[ newNOD ] == 0 ){   ok = 1; // are vecini

                DMax[ newNOD ] = min( DMax[ NOD ]-1 , DMax[ newNOD ] );
                Grad[ newNOD ] --;

                if( DMax[ newNOD ] == 0 ){

                    nrSALVARI ++;
                    SOL[newNOD] = 1;

                    viz[ newNOD ] = 1;
                    Q[ ++Qfn ] = newNOD;
                    DMax[ newNOD ] = 2*M+1;

                }
                else if( Grad[ newNOD ] == 1 ){  // A ramas doar legatura spre centru

                    viz[ newNOD ] = 1;
                    Q[ ++Qfn ] = newNOD;

                }

            }

        }

        if( ok == 0 ) nrfv ++;  // numere fara vecini

        Qst++;
    }

    if( nrfv == 2 && DMax[ Q[Qfn] ] <= M - DMax[ Q[Qfn-1] ] )
        nrSALVARI++;

    if( nrSALVARI <= K ){

        i = 1;
        while( nrSALVARI < K ){     // Completare solutie

            if( SOL[i] == 0 ){
                SOL[i] = 1;
                nrSALVARI++;
            }
            i++;
        }

        return 1;
    }

        return 0;
}

void CautareBinara(){
int k1, k2, mij, R, nimic, i;

    k1 = 1;
    k2 = N;

    while( k1 <= k2 ){

        mij = ( k1 + k2 ) / 2;

        if( Verif(mij) == 1 )
            k2 = mij-1;
        else
            k1 = mij+1;

    }

    nimic = Verif(k1);  // Ca sa se reactualizeze SOL

    fprintf(g,"%d\n",k1);

    for(i=1;i<=N;i++)
        if( SOL[i] == 1 )
            fprintf(g,"%d ",i);

}

int main(){

    Citire();

    if( K == N ){
        fprintf(g,"0\n");
        for(int i=1;i<=N;i++)fprintf(g,"%d ",i);
        return 0;
    }

    CautareBinara();

return 0;
}