zoukankan      html  css  js  c++  java
  • hdu 4856 Tunnels BFS+不回起点的TSP

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4856

    注意到隧道是单向的

    bfs求出距离以后套用TSP模板即可

    注意日本人那本白书上的模板是最后要回到起点的

    而本题并不回起点

    具体的做法是建一个超级起点,跟图中每一个点都建花费为0的边,然后以之为起点跑一边即可

    #include <cstring>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <iostream>
    #include <cstdio>
    #include <stack>
    #include <vector>
    #include <queue>
    #include <map>
    #include <set>
    
    using namespace std;
    
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int, int> P;
    
    const int maxn = 17;
    const int INF = 0x3f3f3f3f;
    
    int n, m;
    char a[maxn][maxn];
    int b[maxn][2];
    int c[maxn][2];
    int d[maxn][maxn];
    
    int dp[1 << maxn][maxn];
    
    const int walk[][2] = {1, 0, 0, 1, -1, 0, 0, -1};
    
    struct Node
    {
        int x, y;
        int s;
    };
    
    bool vis[maxn][maxn];
    void bfs(int u, int v)
    {
        memset(vis, 0, sizeof(vis));
        queue<Node> que;
        Node cur;
    
        cur.x = c[u][0];
        cur.y = c[u][1];
        cur.s = 0;
    
        vis[cur.x][cur.y] = 1;
        que.push(cur);
    
        while(!que.empty())
        {
            cur = que.front();
            que.pop();
            int x = cur.x;
            int y = cur.y;
    
            if(x == b[v][0] && y == b[v][1])
            {
                d[u][v] = cur.s;
                return;
            }
    
            for(int i = 0; i < 4; i++)
            {
                int nx = x + walk[i][0];
                int ny = y + walk[i][1];
    
                if(0 <= nx && nx < n && 0 <= ny && ny < n && a[nx][ny] == '.' && vis[nx][ny] == 0)
                {
                    vis[nx][ny] = 1;
                    Node nxt = {nx, ny, cur.s+1};
                    que.push(nxt);
                }
            }
        }
    
        d[u][v] = INF;
        return;
    }
    
    int main()
    {
        //freopen("in.txt", "r", stdin);
    
        while(scanf("%d%d", &n, &m) == 2)
        {
            for(int i = 0; i < n; i++)
                scanf("%s", a[i]);
    
            for(int i = 0; i < m; i++)
            {
                scanf("%d%d%d%d", &b[i][0], &b[i][1], &c[i][0], &c[i][1]);
    
                b[i][0]--;
                b[i][1]--;
                c[i][0]--;
                c[i][1]--;
            }
    
            for(int i = 0; i < m; i++)
                for(int j = 0; j < m; j++)
                {
                    if(i == j)
                        continue;
    
                    bfs(i, j);
                    bfs(j, i);
                }
    
            for(int i = 0; i <= m; i++)
                d[i][i] = INF;
    
            for(int i = 0; i < m; i++)
                d[i][m] = d[m][i] = 0;
    
            int ans = INF;
    
            m++;
    
            for(int i = 0; i < 1 << m; i++)
                fill(dp[i], dp[i] + m, INF);
    
            dp[((1 << m) - 1)][m-1] = 0;
    
            for(int S = (1 << m) - 1; S >= 0; S--)
                for(int v = 0; v < m; v++)
                    for(int u = 0; u < m; u++)
                        if(!(S >> u & 1))
                        {
                            dp[S][v] = min(dp[S][v], dp[S | 1 << u][u] + d[v][u]);
                            /*if(S == 0 && dp[S][v] < minnum)
                                minnum = dp[S][v];*/
                        }
    
            if(dp[0][m-1] != INF)
                printf("%d
    ", dp[0][m-1]);
            else
                printf("-1
    ");
        }
    
        return 0;
    }
  • 相关阅读:
    lodash函数库----difference
    lodash 函数库-
    lodash函数库 -- chunk
    document.selection.createRange方法----获取用户选择文本
    复制到剪切板 clipboard
    下载图片到本地
    H5(11表格案例:小说排行榜)
    H5(10HTML标签学习)
    H5(09综合案例圣诞老人介绍)
    H5(08常用标签02,绝对,相对路径)
  • 原文地址:https://www.cnblogs.com/dishu/p/4518018.html
Copyright © 2011-2022 走看看