Cod sursa(job #572300)

Utilizator bogfodorBogdan Fodor bogfodor Data 5 aprilie 2011 10:40:11
Problema Reguli Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.92 kb
#include <cstdio>
#include <cmath>
#include <algorithm>
#define Nmax 105
#define inf 0x03f3f3f

using namespace std;

FILE *fin=freopen("munte2.in","r",stdin);
FILE *fout=freopen("munte2.out","w",stdout);

int n,k,l,L;
int ok[Nmax][Nmax];
double d[Nmax][Nmax];
int af[Nmax];
double r=0;

struct punct
{
    float x;
    float y;
}a[Nmax];

double dist(int i,int j)
{
    return sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y));
}

float functie(int i, int j)
{
    float A,B,c;
    A=a[i].y-a[j].y;
    B=a[i].x-a[j].x;
    c=A*A+B*B;
    if(c>L)
        return 0;
    for(int K=i+1;K<j;K++)
    {
        if(a[K].y >= ((a[K].x-a[i].x)*A + a[i].y*B)/B)
            return 0;
    }
    return sqrt(c);
}
void inapoi(int st, int dr)
{
    if(st>=dr)
        return;
    if(ok[st][dr]==1)
        af[dr]=1;
    else
        for(int K=st+1;K<=n;K++)
            if(ok[st][K] && ok[K][dr])
                if(d[st][dr]==d[st][K]+d[K][dr])
                {
                    inapoi(st,K);
                    inapoi(K,dr);
                    return;
                }
}

void afisare()
{
    printf("%d\n",(int)(d[1][n]+0.5));
    for(int i=1;i<n;i++)
        if(af[i])
            printf("%d ",i);
    printf("%d",n);
}

int mic(int x)
{
    for(int i=x;i>=0;i--)
        if(af[i])
            return i;
        return 0;
}

int mare(int x)
{
    for(int i=x;i<=n;i++)
        if(af[i])
            return i;
    return 0;
}

void solve()
{
    L=l*l;
    for(int i=1;i<=n;i++)
        for(int j=i+1;j<=n;j++)
        {
            d[i][j]=functie(i,j);
            if(d[i][j])
                ok[i][j]=1;
        }

    for(int K=1;K<=n;K++)
        for(int i=1;i<=n;i++)
            for(int j=i+1;j<=n;j++){
                if(ok[i][K] && ok[K][j])
                    if(!d[i][j] || ( d[i][j]>d[i][K]+d[K][j]))
                    {
                        ok[i][j]=ok[i][K]+ok[K][j];
                        d[i][j]=d[i][K]+d[K][j];
                    }
            }
    af[1]=1;
    inapoi(1,n);
    if(ok[1][n]==k-1)
        afisare();
    else
    {
        int poz;
        float cost;
        int aux=k-1-ok[1][n];
        while(aux)
        {
            cost=inf;
            for(int i=2;i<=n;i++)
                if(!af[i])
                {
                    int m=mic(i);
                    int M=mare(i);
                    int C=d[m][i]+d[i][M];
                    if(C<cost)
                    {
                        cost=C;
                        poz=i;
                    }
                }
                d[1][n]+=cost;
                af[poz]=1;
                aux--;
        }
        afisare();
    }
}



void citire()
{
    scanf("%d %d %d\n",&n,&k,&l);
    for(int i=1;i<=n;i++)
        scanf("%f %f\n",&a[i].x,&a[i].y);
}

int main()
{
    citire();
    solve();
    return 0;
}