1. 程式人生 > >分書問題(搜尋)

分書問題(搜尋)

D. 分書問題 Time Limit: 1000 ms   Memory Limit: 256 MB
Total Submission: 41   Submission Accepted: 16 Judge By Case Description 已知有n本書(從1~n編號)和n個人(從1~n編號),每個人都有一個自己喜愛的書的列表,現在請你編寫一個程式,設計一種分書方案,使得每個人都能獲得一本書,且這本書一定要在他的喜愛列表中。
Input 輸入資料共若干行,第一行為一個正整數n(n <= 20),從第2行到第n+1行,每行有n個0或1組成,第k行表示編號為k-1的人對這n本書的喜好列表,0表示不喜歡,1表示喜歡。
Output 輸出資料僅一個整數,表示符合條件的分配方案的總數。
Sample Input
Original Transformed
5
00110
11001
01100
00010
01001

Sample Output
Original Transformed
1
題目分析:這個題目我是用dfs做的,dfs好久沒有寫了,還好,雖然耗時有點長,但是最後還是寫出來了。主要是中間那個標誌陣列太菜了,本來可以用一個一維陣列vis【i】表示第i本書是否已經被借走,我剛開始一直用二維陣列,搞得好尷尬。不知道怎麼恢復這個陣列的標誌位。後來一維陣列之後才發現,是在利用過這個之後就直接恢復的。也是我dfs不夠熟練吧。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
char a[25][25];
bool vis[25];
int ans,flag;
int n;
int cou[25];
void dfs(int m,int k){
	//表明第k本書已經被分配 
	if(m>n || m<1 )
	  return ;
	  for(int i=1;i<=n;i++){
	  	if(a[m+1][i] == '1' && vis[i] == 0 ){
			vis[i] = 1;
			if(m+1 == n){
					ans++;
				//	return;
			}
			//如果到達最終邊,直接ans++; 
			else dfs(m+1,i);//否則繼續搜尋 
	        vis[i] = 0;
		}
	  }
}
int main(){
	cin>>n;
	memset(a,-1,sizeof(a));
    char sh[25];
	for(int i=1;i<=n;i++){
			cin>>sh;
			for(int j=0;j<n;j++)
			  a[i][j+1] = sh[j];
	}
	ans=0;   
	for(int i=1;i<=n;i++){
		memset(vis,0,sizeof(vis));
	   	   if(a[1][i] == '1'){
	   	   	 vis[i]=1;
	   	   	 dfs(1,i);
			  }
	   	    
	   }
	cout<<ans<<endl;
	return 0;
}