首页 > 其他 > 详细

FZOJ 2188 过河I (确定状态+BFS)

时间:2015-03-24 09:18:46      阅读:1267      评论:0      收藏:0      [点我收藏+]
技术分享 Problem 2188 过河I

Accept: 27    Submit: 82
Time Limit: 3000 mSec    Memory Limit : 32768 KB

技术分享 Problem Description

一天,小明需要把x只羊和y只狼运输到河对面。船可以容纳n只动物和小明。每次小明划船时,都必须至少有一只动物来陪他,不然他会感到厌倦,不安。不论是船上还是岸上,狼的数量如果超过羊,狼就会把羊吃掉。小明需要把所有动物送到对面,且没有羊被吃掉,最少需要多少次他才可以穿过这条河?

技术分享 Input

有多组数据,每组第一行输入3个整数想x, y, n (0≤?x,?y,n?≤?200)

技术分享 Output

如果可以把所有动物都送过河,且没有羊死亡,则输出一个整数:最少的次数。否则输出 -1 .

技术分享 Sample Input

3 3 233 33 3

技术分享 Sample Output

11-1

技术分享 Hint

第一个样例

次数 船 方向 左岸 右岸(狼 羊)

0: 0 0 3 3 0 0

1: 2 0 > 1 3 2 0

2: 1 0 < 2 3 1 0

3: 2 0 > 0 3 3 0

4: 1 0 < 1 3 2 0

5: 0 2 > 1 1 2 2

6: 1 1 < 2 2 1 1

7: 0 2 > 2 0 1 3

8: 1 0 < 3 0 0 3

9: 2 0 > 1 0 2 3

10: 1 0 < 2 0 1 3

11: 2 0 > 0 0 3 3




思路:求最少的次数,可以想到bfs,关键是确定好状态

设vis[x][y][2] 表示船到达0或1岸后,此岸上的羊数x,和狼数y

而且题目的限制条件很多,可以有很多剪枝,出解很快

//Accepted 2576 625ms GNU C++ 
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;

const int N = 1e5+100;

int head[N];
struct Edge
{
    int to;
    int next;
}es[N<<1];


int son[N];
int n;
int ans1,ans2;
void dfs(int rt,int pa)
{
    int cnt=0;
    bool first=1;
    for(int i=head[rt];~i;i=es[i].next)
    {
        int v=es[i].to;
        if(v==pa) continue;
        if(first)
            first=0;
        else
        {
            ans1++;
            cnt++;
        }
        dfs(v,rt);
    }
    ans2+=cnt/2+cnt%2; //剔除同一节点的分枝数
}

void ini()
{
    memset(head,-1,sizeof(head));
    memset(son,0,sizeof(son));
    ans1=ans2=0;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        ini();
        for(int v=1;v<n;v++)
        {
            int u;
            scanf("%d",&u);
            es[v].to=v;
            es[v].next=head[u];
            head[u]=v;
            es[v+n].to=u;
            es[v+n].next=head[v];
            head[v]=v+n;
            son[u]++;
            son[v]++;
        }
        for(int i=n-1;i>=0;i--)
            if(son[i]==1)
            {
                dfs(i,-1);
                ans1++;
                ans2++;
                break;
            }
        if(ans1)
            printf("%d %d\n",(ans1-1)/2+(ans1-1)%2+1,ans2);
        else
            printf("0 0\n");
    }
    return 0;
}

 


FZOJ 2188 过河I (确定状态+BFS)

原文:http://blog.csdn.net/kalilili/article/details/44572967

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!