HDU 1728 逃离迷宫 BFS

HDU 1728 逃离迷宫

思路:广搜,注意和起点在一条直线上的点转角均为0,还要标记每个点的转角;


注意不同路线到同一个点 转角次数相同,还是需要加入队列。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <queue>
#include <algorithm>
using  namespace std;
#define CLS(x,v)  memset(x,v,sizeof(x))
#define LL long long
#define M 102

int n,m;
char graph[M][M];
struct point{
  int x,y;
  int dir;
  int  step;
  bool operator ==(const point &b){
    return x==b.x&&y==b.y;
  }
  bool ok()
  {
      return x>=0&&x<n&&y>=0&&y<m;
  }
}s,e;
int limit;
queue<point> Q;
int vis[M][M];
int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
int  bfs()
{
    while(!Q.empty())Q.pop();
    CLS(vis,0x7f);
    vis[s.x][s.y]=0;
    point temp,now;
    Q.push(s);
    while(!Q.empty())
    {
        temp=Q.front();
        Q.pop();
        for(int i=0;i<4;i++)
        {
            now.x=temp.x+dir[i][0];
            now.y=temp.y+dir[i][1];
            now.dir=i;
            now.step=temp.step;
            //不是起始点
            if(temp.dir!=-1&&now.dir!=temp.dir)
                   now.step++;
            //剪枝,如果第二次到一个点的转角更小(或相等)则加入队列
            if(now.ok()&&graph[now.x][now.y]=='.'&&now.step<=vis[now.x][now.y])
            {
                if(now.step<=limit)
                {
                   //printf("x==%d  y==%d step==%d\n",now.x,now.y,now.step);
                    if(now==e)return 1;
                    vis[now.x][now.y]=now.step;
                    Q.push(now);
                }
            }
        }


    }
    return 0;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        for(int i=0;i<n;++i)
            scanf("%s",graph[i]);
        scanf("%d%d%d%d%d",&limit,&s.y,&s.x,&e.y,&e.x);
        if(s==e)
        {
            printf("yes\n");
            continue;
        }
        s.y--;s.x--;
        e.y--;e.x--;
        s.dir=-1;s.step=0;
        printf("%s\n",bfs()?"yes":"no");
    }
    return 0;
}
/**
2
3 3
..*
...
*.*
1 1 1 3 2
*/



二分匹配

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <queue>
#include <algorithm>
using  namespace std;
#define CLS(x,v)  memset(x,v,sizeof(x))
#define LL long long
#define M 1002

int n;
int f[M];
void init()
{
    for(int i=0;i<=n;++i)
        f[i]=i;
}
int father(int x)
{
    if(f[x]!=x)
        return f[x]=father(f[x]);
    return x;
}
int main()
{
    int m;
    int x,y;
    while(~scanf("%d",&n)&&n)
    {
        scanf("%d",&m);
        init();
        for(int i=0;i<m;i++)
        {
            scanf("%d%d",&x,&y);
            int fx=father(x);
            int fy=father(y);
            if(fx!=fy)
                f[fx]=fy;
        }
        int cnt=0;
        for(int i=1;i<=n;++i)
        {
            if(f[i]==i)
                cnt++;
        }
         printf("%d\n",cnt-1);
    }

    return 0;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值