码迷,mamicode.com
首页 > 其他好文 > 详细

poj 3740 -- Easy Finding (dfs)

时间:2015-04-07 01:58:23      阅读:130      评论:0      收藏:0      [点我收藏+]

标签:

题目大意:给出一个m行n列的数组,元素只有0和1,

问:能不能找出几行,使得每一列都有且仅有一个1.

 

分析:直接深搜即可

技术分享
#include<iostream>
#include<cstdio>
using namespace std;

int vis[311];//记录该列有1没
int n, m;
int a[20][311];
bool flag;

bool fuhe(int i){
    for (int j = 1; j <= n; j++)
        if (a[i][j] && vis[j])
            return false;
    return true;
}

bool manzu(){//判断是否每一列都有且仅有一个1
    for (int j = 1; j <= n; j++)
        if (!vis[j])
            return false;
    return true;
}

int dfs(int ans){
    int i, j;
    if (ans > m+1)//注意遍历>m时还要判断manzu(),所以应该是超过m+1时才返回
        return false;
    if (manzu()){//每一列都有且仅有一个1
        flag = true;
        return true;
    }
    if (fuhe(ans)){//该行目前看来符合要求
        for (j = 1; j <= n; j++)
            if (a[ans][j])//将该行有1的列全部都设为vis[j]=true;
                vis[j] = 1;
        for (j = ans; j <= m&&!flag; j++){//按行的先后dfs的,小于i行的之前已dfs
            if (dfs(j + 1))//接下来的全部ok,就可以返回true了
                return true;
        }
        //遍历了ans+1到n之后都不行,则该行不行,告诉上一层,回溯
        for (j = 1; j <= n; j++)
            if (a[ans][j])//回溯之前记住要还原
                vis[j] = 0;
        return false;
        }
}

int main()
{
    while (scanf("%d%d", &m, &n) != EOF){
        int i, j;
        for (i = 1; i <= m; i++)
            for (j = 1; j <= n; j++)
                scanf("%d",&a[i][j]);
        memset(vis, 0, sizeof(vis));
        flag = false;
        for (i = 1; i <= m; i++){
            if (dfs(i))
                break;
        }
        if (flag)
            printf("Yes, I found it\n");
        else
            printf("It is impossible\n");
    }
    return 0;
}
View Code

题目链接:http://poj.org/problem?id=3740

poj 3740 -- Easy Finding (dfs)

标签:

原文地址:http://www.cnblogs.com/lxzd723/p/4397264.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!