• UVA 437 The Tower of Babylon


     1 #include <iostream>
     2 #include <cstdio>
     3 #include <climits>
     4 #include <cstring>
     5 #include <cstdlib>
     6 #include <cmath>
     7 #include <vector>
     8 #include <queue>
     9 #include <algorithm>
    10 #define esp 1e-6
    11 #define pb push_back
    12 #define in  freopen("in.txt", "r", stdin);
    13 #define out freopen("out.txt", "w", stdout);
    14 #define print(a) printf("%d
    ",(a));
    15 #define bug puts("********))))))");
    16 #define Rep(i, c) for(__typeof(c.end()) i = c.begin(); i != c.end(); i++)
    17 #define inf 0x0f0f0f0f
    18 using namespace std;
    19 typedef long long  LL;
    20 typedef vector<int> VI;
    21 typedef vector<int>:: iterator IT;
    22 typedef pair<int, int> pii;
    23 #define N 300
    24 int x[N], y[N], z[N];
    25 int G[N][N], dp[N];
    26 int n;
    27 int f(int i)
    28 {
    29     int ans = dp[i];
    30     if(ans > 0)
    31         return ans;
    32     ans = z[i];
    33     for(int j = 1; j <= n*3; j++)
    34         if(G[i][j])
    35             ans = max(ans, f(j)+z[i]);
    36     return dp[i] = ans;
    37 }
    38 bool check(int i, int j)
    39 {
    40     return (x[i]>x[j] && y[i] > y[j]) || (x[i] > y[j] && y[i] > x[j]);
    41 }
    42 int main(void)
    43 {
    44     int t =1;
    45     while(scanf("%d", &n), n)
    46     {
    47         memset(dp, -1, sizeof(dp));
    48         memset(G, 0, sizeof(G));
    49         for(int i = 1; i <= n; i++)
    50         {
    51             scanf("%d%d%d", x+i, y+i, z+i);
    52             x[n+i] = z[i], y[n+i] = x[i], z[n+i] = y[i];
    53             x[2*n+i] = y[i], y[2*n+i] = z[i], z[2*n+i] = x[i];
    54         }
    55         for(int i = 1; i <= n*3; i++)
    56             for(int j = 1; j <= n*3; j++)
    57             {
    58                 if(check(i,j))
    59                     G[i][j] = 1;
    60             }
    61         int ans = 0;
    62         for(int i = 1; i <= n*3; i++)
    63             ans = max(ans, f(i));
    64         printf("Case %d: maximum height = %d
    ", t, ans);
    65         t++;
    66     }
    67     return 0;
    68 }
    View Code

     上面的是普通dp做法,将每种砖头,拆成3个点,分别表示不同的高度,然后不同的砖头(i,j),如果j能放到i上面,那么建一条边从i->j,权重为j的高z[j],由于最下层可能为任何一块砖头,的任何一面作为塔的底部,可以从0分别建立一条到所有砖头i的边,权重为z[i],这样问题转化为求从源点src = 0,出发的最长路径了,类比最短路的做法,可以用spfa,基于优先队列的dijkstra。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <climits>
    #include <cstring>
    #include <cstdlib>
    #include <cmath>
    #include <vector>
    #include <queue>
    #include <algorithm>
    #define esp 1e-6
    #define pb push_back
    #define in  freopen("in.txt", "r", stdin);
    #define out freopen("out.txt", "w", stdout);
    #define print(a) printf("%d
    ",(a));
    #define bug puts("********))))))");
    #define Rep(i, c) for(__typeof(c.end()) i = c.begin(); i != c.end(); i++)
    #define inf 0x0f0f0f0f
    using namespace std;
    typedef long long  LL;
    typedef vector<int> VI;
    typedef vector<int>:: iterator IT;
    typedef pair<int, int> pii;
    #define N 100
    #define M 10000
    struct EDGE
    {
        int i, c;
        EDGE *next, *ani;
    } *Edge[N], E[M];
    int x[N], y[N], z[N];
    int cnt, dis[N];
    VI dist;
    void add(int i, int j, int c, EDGE &e1)
    {
        e1.i = j, e1.c = c, e1.next = Edge[i], Edge[i] = &e1;
    //    e2.i = i, e2.c = c, e2.ani = &e1, e2.next = Edge[j], Edge[j] = &e2;
        cnt++;
    }
    bool check(int i, int j)
    {
        return (x[i] > x[j] && y[i] > y[j]) || (x[i] > y[j] && y[i] > x[j]);
    }
    void init(void)
    {
        memset(Edge, 0, sizeof(Edge));
        cnt = 0;
    }
    void spfa(int src)
    {
        int inq[N];
        memset(inq, 0, sizeof(inq));
        queue<int> q;
        q.push(src);
        inq[src] = 1;
        while(!q.empty())
        {
            int u = q.front();
            q.pop();
            inq[u] = 0;
            int v;
            for(EDGE  *p = Edge[u]; p; p = p->next)
            {
                if(dist[v = p->i] < dist[u] + p->c)
                    if(dist[v] = dist[u] + p->c, !inq[v])
                        inq[v] = 1 , q.push(v);
            }
        }
    }
    int main(void)
    {
    
        int t = 1;
        int n;
        while(scanf("%d", &n), n)
        {
            init();
            for(int i = 1; i <= n; i++)
            {
                scanf("%d%d%d", x+i, y+i, z+i);
                x[n+i] = y[i], y[n+i] = z[i], z[n+i] = x[i];
                x[2*n+i] = x[i], y[2*n+i] = z[i], z[2*n+i] = y[i];
            }
            for(int i = 1; i <= n*3; i++)
            {
                for(int j = 1; j <= n*3; j++)
                    if(check(i,j))
                        add(i, j, z[j], E[cnt]);
                add(0, i, z[i], E[cnt]);
            }
            dist.clear();
    //        dist.resize(3*n+1);
            for(int i = 0; i <= 3*n; i++)
                dist[i] = 0;
            spfa(0);
            printf("Case %d: maximum height = %d
    ", t, *max_element(dist.begin(), dist.end()));
            t++;
        }
        return 0;
    }
    

     dijkstra:

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <climits>
      4 #include <cstring>
      5 #include <cstdlib>
      6 #include <cmath>
      7 #include <vector>
      8 #include <queue>
      9 #include <algorithm>
     10 #define esp 1e-6
     11 #define pb push_back
     12 #define in  freopen("in.txt", "r", stdin);
     13 #define out freopen("out.txt", "w", stdout);
     14 #define print(a) printf("%d
    ",(a));
     15 #define bug puts("********))))))");
     16 #define Rep(i, c) for(__typeof(c.end()) i = c.begin(); i != c.end(); i++)
     17 #define inf 0x0f0f0f0f
     18 using namespace std;
     19 typedef long long  LL;
     20 typedef vector<int> VI;
     21 typedef vector<int>:: iterator IT;
     22 typedef pair<int, int> pii;
     23 using namespace std;
     24 #define N 100
     25 #define M 10000
     26 struct EDGE
     27 {
     28     int i, c;
     29     EDGE *next, *ani;
     30 } *Edge[N], E[M];
     31 int x[N], y[N], z[N];
     32 int cnt, dis[N];
     33 VI dist;
     34 void add(int i, int j, int c, EDGE &e1)
     35 {
     36     e1.i = j, e1.c = c, e1.next = Edge[i], Edge[i] = &e1;
     37 //    e2.i = i, e2.c = c, e2.ani = &e1, e2.next = Edge[j], Edge[j] = &e2;
     38     cnt++;
     39 }
     40 bool check(int i, int j)
     41 {
     42     return (x[i] > x[j] && y[i] > y[j]) || (x[i] > y[j] && y[i] > x[j]);
     43 }
     44 void init(void)
     45 {
     46     memset(Edge, 0, sizeof(Edge));
     47     cnt = 0;
     48 }
     49 struct cmp
     50 {
     51     bool operator () (const pii a, const pii b)
     52     {
     53         return a.first < b.first;
     54     }
     55 };
     56 void dij(void)
     57 {
     58     priority_queue<pii, vector<pii> ,cmp > q;
     59     q.push(make_pair(0, 0));
     60     while(!q.empty())
     61     {
     62         pii u = q.top();
     63         int x = u.second;
     64         q.pop();
     65         int y;
     66         if(dist[x] == u.first)
     67         {
     68             for(EDGE *p = Edge[x]; p; p = p->next)
     69             {
     70                 if(dist[y = p->i] < dist[x] + p->c)
     71                 {
     72                     dist[y] = dist[x] + p->c;
     73                     q.push(make_pair(dist[y], y));
     74                 }
     75             }
     76         }
     77     }
     78 }
     79 int main(void)
     80 {
     81     
     82     int t = 1;
     83     int n;
     84     while(scanf("%d", &n), n)
     85     {
     86         init();
     87         for(int i = 1; i <= n; i++)
     88         {
     89             scanf("%d%d%d", x+i, y+i, z+i);
     90             x[n+i] = y[i], y[n+i] = z[i], z[n+i] = x[i];
     91             x[2*n+i] = x[i], y[2*n+i] = z[i], z[2*n+i] = y[i];
     92         }
     93         for(int i = 1; i <= n*3; i++)
     94         {
     95             for(int j = 1; j <= n*3; j++)
     96                 if(check(i,j))
     97                     add(i, j, z[j], E[cnt]);
     98             add(0, i, z[i], E[cnt]);
     99         }
    100         dist.clear();
    101         dist.resize(3*n+1);
    102 //        for(int i = 0; i <= 3*n; i++)
    103 //            dist[i] = 0;
    104         dij();
    105         printf("Case %d: maximum height = %d
    ", t, *max_element(dist.begin(), dist.end()));
    106         t++;
    107     }
    108     return 0;
    109 }
    View Code
  • 相关阅读:
    enca工具,检测文件编码
    ubuntu 支持gbk
    LinkedList线程安全问题
    php防止form重复提交的方法
    Linux 内存泄露调试工具
    从B树、B+树、B*树谈到R 树
    Ubuntu 语言设置
    wwwauthenticate
    Lua脚本语法说明
    jQuery学习总结之元素的相对定位和选择器持续更新中
  • 原文地址:https://www.cnblogs.com/rootial/p/3321698.html
Copyright © 2020-2023  润新知