UVA 437The Tower of Babylon - 简单dp

来源:互联网 发布:一首歌火了网络歌手 编辑:程序博客网 时间:2024/05/18 02:38

题目描述](http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=19214)

分析:

因为每种都有无穷多个,所以可以将每个立方体拆成三个正方形,且每种立方体只拆一次。
每个正方形向底面长宽严格小于它的正方形连有向边,有向边的权值为这个正方形属于的立方体除了这个正方形边长的另一边的长,求最长路。

#include<cstdio>#include<cstring>#include<queue>#include<algorithm>using namespace std;#define MAXN 30struct node{    int u,v,w;    node *next;}edge[MAXN*MAXN*9+10],*adj[MAXN*3+10],*ecnt=&edge[0];struct Mat{    int a,b,h;}trix[MAXN*3+10];int n,cntt,dp[MAXN*3+10],ans,in[MAXN*3+10];void Init(){    ecnt=&edge[0];    memset(adj,0,sizeof adj);    cntt=0;    memset(in,0,sizeof in);}inline void Insert(int x,int y,int z){    ++cntt;    trix[cntt].a=x,trix[cntt].b=y,trix[cntt].h=z;}bool check(int i,int j){    if((trix[i].a>trix[j].a&&trix[i].b>trix[j].b)||(trix[i].a>trix[j].b&&trix[i].b>trix[j].a))        return true;    else        return false;}void addedge(int u,int v,int w){    in[v]++;    node *p=++ecnt;    p->v=v;    p->w=w;    p->next=adj[u];    adj[u]=p;}void read(){    int x,y,z;    for(int i=1;i<=n;i++){        scanf("%d%d%d",&x,&y,&z);        Insert(x,y,z);        Insert(x,z,y);        Insert(y,z,x);    }    for(int i=1;i<=cntt;i++)        for(int j=1;j<=cntt;j++)            if(check(i,j))                addedge(i,j,trix[j].h);}void DP(){    int u;    queue<int> que;    for(int i=1;i<=cntt;i++){        if(!in[i]){            que.push(i);            dp[i]=trix[i].h;        }        else            dp[i]=0;    }    while(!que.empty()){        u=que.front(); que.pop();        for(node *p=adj[u];p;p=p->next)            if(dp[p->v]<=dp[u]+p->w){                dp[p->v]=dp[u]+p->w;                que.push(p->v);            }    }    ans=0;    for(int i=1;i<=cntt;i++)        ans=max(ans,dp[i]);    printf("%d\n",ans);}int main(){    int cas=0;    while(scanf("%d",&n)&&n){        Init();        read();        printf("Case %d: maximum height = ",++cas);        DP();    }}
0 0