题目背景
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() { ,f=; char ch=getchar(); ') ch=getchar(); +ch-'; 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,,sizeof(dis)); memset(vis,,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(); ;i<=n;i++) a[i]=read(); ;i<n;i++) ;j<=n;j++) { x=read(); if(x) add(i,j); } ;i<=n;i++) { maxn=ans; memset(fa,-,sizeof(fa)); spfa(i); ;i<=n;i++) if(ans<dis[i]) ans=dis[i],e=i; if(ans==maxn) continue; sum=; ;j=fa[j]) pre[++sum]=j; } ;i--) printf("%d ",pre[i]); printf("\n%d",ans); ; }