UVA437 - The Tower of Babylon

有向无环图最长路径算法
每个立方体都可以分别以三个边为高,这样一个立方体确定高后,就有三个状态,存储在cube中。
在用Graph邻接数组存储每个状态之间的关系,这样就形成了有向无环图。在用dp[i] = max(dp[i], solve(j) + cube[i].h)(i -> j),求出每个d[i],取最大值输出.

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <map>
#include <vector>
using namespace std;

struct Cube{
    Cube(){}
    Cube(int a, int b, int c)
    {
        x = a;
        y = b;
        h = c;
    }
    int x, y;
    int h;
}cube[100];
int Graph[100][100];
int dp[100], n;
bool judge(Cube &a, Cube &b)
{
    if(a.x < a.y)
        swap(a.x, a.y);
    if(b.x < b.y)
        swap(b.x, b.y);
    if(a.x > b.x && a.y > b.y)
        return true;
    return false;
}
int solve(int m)
{
    if(dp[m])return dp[m];
    dp[m] = cube[m].h;
    for(int i = 1; i <= 3 * n; i++)
    {
        if(Graph[m][i])
            dp[m] = max(dp[m], solve(i) + cube[m].h);
    }
    return dp[m];
}
int main()
{
  // freopen("in.txt", "r", stdin);
    int cas =0;
    while(cin >> n && n)
    {
        memset(Graph, 0, sizeof(Graph));
        memset(dp, 0, sizeof(dp));
        for(int i = 1; i <= n; i++)
        {
            int x, y, z;
            cin >> x >> y >> z;
            cube[3*i] = Cube(x, y, z);
            cube[3*i-1] = Cube(x, z, y);
            cube[3*i-2] = Cube(y, z, x);
        }
        for(int i = 1; i <= 3 * n; i++)
            for(int j = i+1; j <= 3 * n; j++)
        {
            if(judge(cube[i], cube[j]))
               Graph[i][j] = 1;
            else if(judge(cube[j], cube[i]))
                Graph[j][i] = 1;
        }
        int maxs = 0;
        for(int i = 1; i <= 3 * n; i++)
        {
            dp[i] = solve(i);
            maxs = max(maxs, dp[i]);
        }

        printf("Case %d: maximum height = %d\n", ++cas, maxs);
    }

    return 0;
}

你可能感兴趣的:(UVA437 - The Tower of Babylon)