HDU 4671 Backup Plan 构造

负载是否平衡只与前两列有关,剩下的只要与前两列不重复就随便放。

第一列我们按1-n这样循环放,第二列每次找个数最少的那个服务器放。

#include <cstdio>

#include <cstring>

#include <cstdlib>



using namespace std;



const int MAXN = 110;



int N, M;

int mat[MAXN][MAXN];

int cnt[MAXN];

int ori[MAXN];

bool vis[MAXN];



void show()

{

    for ( int i = 1; i <= M; ++i )

    {

        for ( int j = 1; j <= N; ++j )

        {

            if ( j != 1 ) putchar(' ');

            printf( "%d", mat[i][j] );

        }

        puts("");

    }

    //puts("=========");

    return;

}



void FangHang( int *a )

{

    memset( vis, false, sizeof(vis) );

    vis[ a[1] ] = true;

    vis[ a[2] ] = true;



    for ( int i = 3; i <= N; ++i )

    {

        for ( int j = 1; j <= N; ++j )

        if ( !vis[j] )

        {

            a[i] = j;

            vis[j] = true;

            break;

        }

    }



    return;

}



int GetMin( int now )

{

    int minn = 1 << 30;

    int ansi;

    for ( int i = 1; i <= N; ++i )

    {

        if ( i == now ) continue;

        if ( cnt[i] < minn )

        {

            minn = cnt[i];

            ansi = i;

        }

    }

    return ansi;

}



void solved()

{

    memset( cnt, 0, sizeof(cnt) );

    for ( int i = 1; i <= M; ++i )

        ++cnt[ mat[i][1] ];



    int fang = 0;

    int cur = 1;

    for ( int i = 1; i <= N; ++i ) ori[i] = cnt[i];

    while ( fang < M )

    {

        int minn;

        int j = 1;

        while ( j <= M )

        {

            minn = GetMin(cur);

            for ( ; j <= M; ++j )

            {

                if ( mat[j][1] == cur && mat[j][2] == -1 )

                {

                    mat[j][2] = minn;

                    ++cnt[ minn ];

                    ++fang;

                    break;

                }

            }

        }

        for ( int i = 1; i <= N; ++i ) cnt[i] = ori[i];

        ++cur;

    }



    for ( int i = 1; i <= M; ++i )

    {

        FangHang( mat[i] );

    }



    return;

}



int main()

{

    while ( scanf( "%d%d", &N, &M ) == 2 )

    {

        memset( mat, -1, sizeof(mat) );

        int i = 1, j = 1;

        while ( i <= M )

        {

            mat[i][1] = j;

            ++i, ++j;

            if ( j > N ) j = 1;

        }

        solved();

        show();

    }

    return 0;

}

 

你可能感兴趣的:(backup)