1. 程式人生 > 實用技巧 >洛谷 P2196 挖地雷 (dfs)

洛谷 P2196 挖地雷 (dfs)

題目描述

在一個地圖上有N個地窖(N20),每個地窖中埋有一定數量的地雷。同時,給出地窖之間的連線路徑。當地窖及其連線的資料給出之後,某人可以從任一處開始挖地雷,然後可以沿著指出的連線往下挖(僅能選擇一條路徑),當無連線時挖地雷工作結束。設計一個挖地雷的方案,使某人能挖到最多的地雷。

輸入格式

有若干行。

1行只有一個數字,表示地窖的個數N

2行有N個數,分別表示每個地窖中的地雷個數。

3行至第N+1行表示地窖之間的連線情況:

3行有n1個數(0或1),表示第一個地窖至第2個、第3個、…、第n個地窖有否路徑連線。如第3行為1 1 0 0 0 … 0,則表示第1個地窖至第2個地窖有路徑,至第3個地窖有路徑,至第4個地窖、第5個、…、第n個地窖沒有路徑。

4行有n2個數,表示第二個地窖至第3個、第4個、…、第n個地窖有否路徑連線。

… …

n+1行有1個數,表示第n1個地窖至第n個地窖有否路徑連線。(為0表示沒有路徑,為1表示有路徑)。

輸出格式

有兩行

第一行表示挖得最多地雷時的挖地雷的順序,各地窖序號間以一個空格分隔,不得有多餘的空格。

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

輸入輸出樣例

輸入 #1
5
10 8 4 7 6
1 1 1 0
0 0 0
1 1
1
輸出 #1
1 3 4 5
27



由於資料很小,我又不太會dp,可以直接暴搜。順便鞏固一下dfs和回溯的寫法。我沒有進行任何剪枝。

#include<iostream>
#include
<cstdio> #include<algorithm> #include<cstring> using namespace std; int ans[25],temp[25],tot,maxmine,l,ll; //ans記錄最終答案路徑,temp記錄每次搜尋路徑,tot記錄每次搜尋的地雷數 //maxmine記錄最終答案地雷數量,l記錄每次搜尋經過的房間數量,ll記錄最終答案房間數量 bool map[25][25];//記錄 i,j 之間有無通路 int a,n[25]; void refresh() { ll=l; maxmine=tot;
for(int i=0;i<ll;i++) ans[i]=temp[i]; return ; } int read() { int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') { x=x*10+ch-'0'; ch=getchar(); } return x*f; } void dfs(int x,int st) { if(tot>maxmine) refresh(); for(int i=st;i<=a;i++) if(map[x][i]==1) { tot+=n[i]; temp[l++]=i; dfs(i,i+1); l--; tot-=n[i]; } } int main() { a=read(); for(int i=1;i<=a;i++) n[i]=read(); memset(map,0,sizeof(map)); for(int i=1;i<a;i++) for(int j=i+1;j<=a;j++) map[i][j]=read(); for(int i=1;i<=a;i++) { tot+=n[i]; temp[l++]=i; dfs(i,i+1); tot-=n[i]; l--; } for(int i=0;i<ll;i++) { if(i) printf(" "); printf("%d",ans[i]); } printf("\n%d",maxmine); return 0; }
暴搜