您的位置:首页 > 其它

hdu 4771 Stealing Harry Potter's Precious (2013 杭州 onsite B题)bfs预处理后,dfs枚举或tsp

2013-11-09 21:07 489 查看
2013 杭州 onsite B题

bfs预处理后,dfs枚举或tsp

bfs预处理后,dfs枚举:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
#include<map>
#include <queue>
#define REP(i, n) for(int i=0; i<n; i++)
#define FF(i, a, b) for(int i=a; i<b; i++)
#define FD(i, a, b) for(int i=a; i>=b; i--)
#define LL long long
#define PB push_back
#define CLR(a, b) memset(a, b, sizeof(a))
using namespace std;

const int INF = 0x3f3f3f3f;
int n, m;
int k;
int di[] = {0, 1, 0, -1};
int dj[] = {1, 0, -1, 0};
char mat[110][110];
int dis[5][110][110];
int g[6][2];
int op[6];
int vis[6];
int ans;

void dfs(int step, int now)
{
    if (step > k)
    {
        ans = min(ans, now);
        return ;
    }
    int fr = op[step - 1];
    for (int r = 1; r <= k; r++)
    {
        if (!vis[r])
        {
            vis[r] = 1;
            op[step] = r;
            int to = r;
            dfs(step + 1, now + dis[fr][g[to][0]][g[to][1]]);
            vis[r] = 0;
        }
    }
}

bool check(int i, int j)
{
    if (i >= 0 && i < n && j >= 0 && j < m) return 1;
    return 0;
}

bool bfs(int step)
{
    CLR(dis[step], INF);
    int si = g[step][0];
    int sj = g[step][1];
    dis[step][si][sj] = 0;
    queue<int>q;
    while (!q.empty()) q.pop();
    q.push(si * 1000 + sj);
    int num = 0;
    while (!q.empty())
    {
        int u = q.front(); q.pop();
        int ui = u / 1000;
        int uj = u % 1000;
        if (mat[ui][uj] <= '9' && mat[ui][uj] >= '0') num++;
        if (num == k + 1) return 1;
        REP(r, 4)
        {
            int vi = ui + di[r];
            int vj = uj + dj[r];
            if (check(vi, vj) && mat[vi][vj] != '#' && dis[step][vi][vj] > dis[step][ui][uj] + 1)
            {
                dis[step][vi][vj] = dis[step][ui][uj] + 1;
                q.push(vi * 1000 + vj);
            }
        }
    }
    return 0;
}

int main()
{
    int x, y;
    while(scanf("%d%d", &n, &m), n+m)
    {
        REP(i, n)
        {
            scanf("%s", mat[i]);
            REP(j, m)
            {
                if (mat[i][j] == '@')
                {
                    g[0][0] = i;
                    g[0][1] = j;
                    mat[i][j] = '0';
                }
            }
        }
        scanf("%d", &k);
        for (int i = 1; i <= k; i++)
        {
            scanf("%d%d", &x, &y);
            x--;
            y--;
            g[i][0] = x;
            g[i][1] = y;
            mat[x][y] = '0' + i;
        }
        if (!bfs(0))
        {
            printf("-1\n");
        }
        else
        {
            FF(i, 1, k + 1) bfs(i);
            ans = INF;
            op[0] = 0;
            CLR(vis, 0);
            vis[0] = 1;
            dfs(1, 0);
            printf("%d\n", ans);
        }
    }
    return 0;
}


bfs预处理后,tsp:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
#include<map>
#include <queue>
#define REP(i, n) for(int i=0; i<n; i++)
#define FF(i, a, b) for(int i=a; i<b; i++)
#define FD(i, a, b) for(int i=a; i>=b; i--)
#define LL long long
#define PB push_back
#define CLR(a, b) memset(a, b, sizeof(a))
using namespace std;

const int INF = 0x3f3f3f3f;
int n, m;
int k;
int di[] = {0, 1, 0, -1};
int dj[] = {1, 0, -1, 0};
char mat[110][110];
int dis[5][110][110];
int g[6][2];
int ans;
int dp[5][1 << 5];

bool check(int i, int j)
{
    if (i >= 0 && i < n && j >= 0 && j < m) return 1;
    return 0;
}

bool bfs(int step)
{
    CLR(dis[step], INF);
    int si = g[step][0];
    int sj = g[step][1];
    dis[step][si][sj] = 0;
    queue<int>q;
    while (!q.empty()) q.pop();
    q.push(si * 1000 + sj);
    int num = 0;
    while (!q.empty())
    {
        int u = q.front(); q.pop();
        int ui = u / 1000;
        int uj = u % 1000;
        if (mat[ui][uj] <= '9' && mat[ui][uj] >= '0') num++;
        if (num == k + 1) return 1;
        REP(r, 4)
        {
            int vi = ui + di[r];
            int vj = uj + dj[r];
            if (check(vi, vj) && mat[vi][vj] != '#' && dis[step][vi][vj] > dis[step][ui][uj] + 1)
            {
                dis[step][vi][vj] = dis[step][ui][uj] + 1;
                q.push(vi * 1000 + vj);
            }
        }
    }
    return 0;
}

int solve()
{
    CLR(dp, INF);
    dp[0][1] = 0;
    int ALL = (1 << (k + 1)) - 1;
    for (int ss = 0; ss <= ALL; ss++)
    {
        for (int i = 1; i <= k; i++)
        {
            for (int j = 0; j <= k; j++)
            {
                if (i != j && (ss & (1 << i)))
                {
                    dp[i][ss] = min(dp[i][ss], dp[j][ss ^ (1 << i)] + dis[j][g[i][0]][g[i][1]]);
                }
            }
        }
    }
    int ans = INF;
    for (int i = 0; i <= k; i++)
        ans = min(ans, dp[i][ALL]);
    return ans;
}

int main()
{
    int x, y;
    while(scanf("%d%d", &n, &m), n+m)
    {
        REP(i, n)
        {
            scanf("%s", mat[i]);
            REP(j, m)
            {
                if (mat[i][j] == '@')
                {
                    g[0][0] = i;
                    g[0][1] = j;
                    mat[i][j] = '0';
                }
            }
        }
        scanf("%d", &k);
        for (int i = 1; i <= k; i++)
        {
            scanf("%d%d", &x, &y);
            x--;
            y--;
            g[i][0] = x;
            g[i][1] = y;
            mat[x][y] = '0' + i;
        }
        if (!bfs(0))
        {
            printf("-1\n");
        }
        else
        {
            FF(i, 1, k + 1) bfs(i);
            printf("%d\n", solve());
        }
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: