首页 > 代码库 > 挖地雷问题(DAG最长路)

挖地雷问题(DAG最长路)

挖地雷问题

(P3.pas/c/cpp)

来源:NOIP1996(提高组)第三题(有改动)

【问题描述】

    在一个地图上有N个地窖(N<=20),每个地窖中埋有一定数量的地雷。同时,给出地窖之间的连接路径。

当地窖及其连接的数据给出之后,某人可以从任一处开始挖地雷,然后可以沿着指出的连接往下挖(仅能选择一条路径),当无连接时挖地雷工作结束。设计一个挖地雷的方案,使某人能挖到最多的地雷。

【输入文件】

    N:(表示地窖的个数)

   W1W2W3,……WN(表示每个地窖中埋藏的地雷数量)

     A12…………… .     A1N     

     A23…………..A2N       

     ……..

    AN-1N

【输出文件】

    K1--K2--……….KV            (挖地雷的顺序)

    MAX                           (挖地雷的数量)

【输入样例】            //////整一个类数字三角形

5

108476

1 1 1 0

0 0 0

1 1

1

【输出样例】

1->3->4->5

max=27


思路:

dp[ i ]表示 以i为起点的挖到最多的雷数;

dp[ i ]=w[ i ]+max{ dp[ j ]  | (i ,j )通路 };



#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define N 210
using namespace std;

int w[N];
int dp[N];

struct node{
    int to;
    int next;
}edge[N*N];

int pre[N];
int path[N];

int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        memset(dp,0,sizeof dp);
        memset(pre,-1,sizeof pre);
        memset(path,0,sizeof path);
        for(int i=1;i<=n;i++)
            scanf("%d",w+i);
        int v;
        int cnt=0;
        for(int i=1;i<n;i++)
            for(int j=i+1;j<=n;j++)
            {
                scanf("%d",&v);               //邻接表
                if(v)
                {
                    edge[cnt].to=j;
                    edge[cnt].next=pre[i];
                    pre[i]=cnt++;
                }
            }
        dp[n]=w[n];
        int maxx=0;
        int u;
        int p;
        for(int i=n-1;i>=1;i--)      //dp
        {
            u=pre[i];
            while(u)
            {
                v=edge[u].to;
                if(dp[v]>maxx)
                {
                    maxx=dp[v];
                    p=v;
                }
                u=edge[u].next;
            }
            path[i]=p;             //路<span style="font-family:Times New Roman;">径记录</span>
            dp[i]=maxx+w[i];
        }
        int k=1;
        for(int i=1;i<=n;i++)
            if(dp[i]>dp[k]) k=i;
        maxx=dp[k];
        printf("%d",k);
        k=path[k];
        while(k)
        {
            printf("->%d",k);
            k=path[k];
            //printf("%d",k);
        }
        cout<<endl<<maxx<<endl;
    }
    return 0;
}

挖地雷问题(DAG最长路)