洛谷——P2196 挖地雷

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷——P2196 挖地雷相关的知识,希望对你有一定的参考价值。

题目背景

NOIp1996提高组第三题

题目描述

在一个地图上有N个地窖(N<=20),每个地窖中埋有一定数量的地雷。同时,给出地窖之间的连接路径。当地窖及其连接的数据给出之后,某人可以从任一处开始挖地雷,然后可以沿着指出的连接往下挖(仅能选择一条路径),当无连接时挖地雷工作结束。设计一个挖地雷的方案,使某人能挖到最多的地雷。

输入输出格式

输入格式:

 

输入文件mine.in有若干行。

第1行只有一个数字,表示地窖的个数N。

第2行有N个数,分别表示每个地窖中的地雷个数。

第3行至第N+1行表示地窖之间的连接情况:

第3行有n-1个数(0或1),表示第一个地窖至第2个、第3个、…、第n个地窖有否路径连接。如第3行为1 1 0 0 0 … 0,则表示第1个地窖至第2个地窖有路径,至第3个地窖有路径,至第4个地窖、第5个、…、第n个地窖没有路径。

第4行有n-2个数,表示第二个地窖至第3个、第4个、…、第n个地窖有否路径连接。

… …

第n+1行有1个数,表示第n-1个地窖至第n个地窖有否路径连接。(为0表示没有路径,为1表示有路径)。

 

输出格式:

 

输出文件wdl.out有两行数据。

第一行表示挖得最多地雷时的挖地雷的顺序,各地窖序号间以一个空格分隔,不得有多余的空格。

第二行只有一个数,表示能挖到的最多地雷数。

 

输入输出样例

输入样例#1:
5
10 8 4 7 6
1 1 1 0
0 0 0
1 1
1
输出样例#1:
1 3 4 5
27


最短路,跑n遍spfa,每次记录最长的路径的长度以及最长路径经过的点,我们判断我们记录的路径是否需要更新,如果需要更新(即判断当前路径是否为最长的),更新路径
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 50
using namespace std;
bool vis[N];
queue<int>q;
int n,x,tot,ans,maxn,sum,e;
int a[N],fa[N],pre[N],dis[N],head[N];
int read()
{
    int x=0,f=1; char ch=getchar();
    while(ch<0||ch>9) ch=getchar();
    while(ch>=0&&ch<=9){x=x*10+ch-0; ch=getchar();}
    return x*f;
}
struct Edge
{
    int to,next,from;
}edge[N];
int add(int x,int y)
{
    tot++;
    edge[tot].to=y;
    edge[tot].next=head[x];
    head[x]=tot;
}
int spfa(int s)
{
    memset(dis,0,sizeof(dis));
    memset(vis,0,sizeof(vis));
    dis[s]=a[s];
    q.push(s),vis[s]=true;
    while(!q.empty())
    {
        int x=q.front(); q.pop();vis[x]=false;
        for(int i=head[x];i;i=edge[i].next)
        {
            int to=edge[i].to;
            if(dis[to]<=dis[x]+a[to])
            {
                dis[to]=dis[x]+a[to];
                fa[to]=x;
                if(vis[to]) continue;
                q.push(to),vis[to]=true;
            }
        }
    }
}
int main()
{
    n=read();
    for(int i=1;i<=n;i++) a[i]=read();
    for(int i=1;i<n;i++)
     for(int j=i+1;j<=n;j++)
     {
         x=read();
        if(x) add(i,j);
      } 
    for(int i=1;i<=n;i++) 
    {
        maxn=ans;
        memset(fa,-1,sizeof(fa));
        spfa(i);
        for(int i=1;i<=n;i++)
         if(ans<dis[i]) ans=dis[i],e=i;
        if(ans==maxn) continue; 
        sum=0;
        for(int j=e;j!=-1;j=fa[j])
           pre[++sum]=j;
    }
    for(int i=sum;i>=1;i--) printf("%d ",pre[i]);
    printf("\n%d",ans);
    return 0;
 }

 


以上是关于洛谷——P2196 挖地雷的主要内容,如果未能解决你的问题,请参考以下文章

P2196 挖地雷

P2196 挖地雷

P2196 挖地雷

Luogu P2196 挖地雷

P2196 [NOIP1996 提高组] 挖地雷DP和图论的简单结合

挖地雷问题