FZU2186

来源:互联网 发布:wifi网络精灵 编辑:程序博客网 时间:2024/05/16 07:45

题目链接

#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <cstdlib>#include <queue>using namespace std;const int maxn = 110;const int INF = 0x3f3f3f3f;int n, m, tot;int grid[maxn][maxn], dist[maxn][maxn], dp[1 << 12][20], vis[maxn][maxn];int dx[4] = { 1,0,0,-1 };int dy[4] = { 0,1,-1,0 };struct Point{    int x, y;    Point(){}    Point(int _x, int _y) :x(_x), y(_y){}}poi[maxn];struct Node{    int x, y, dist;    Node(int _x,int _y,int _dist):x(_x),y(_y),dist(_dist){}};int BFS(int Start, int End)//BFS求最短距离{    memset(vis, false, sizeof(vis));    queue<Node> que;    que.push(Node(poi[Start].x, poi[Start].y, 0));    int step, x, y;    while (!que.empty())    {        Node front = que.front();        que.pop();        if (front.x == poi[End].x&&front.y == poi[End].y)            return front.dist;        for (int i = 0; i < 4; i++)        {            int nowx = front.x + dx[i];            int nowy = front.y + dy[i];            if (nowx < 1 || nowx > n || nowy < 1 | nowy > m || grid[nowx][nowy] < 0)                continue;            if (!vis[nowx][nowy])            {                vis[nowx][nowy] = 1;                step = front.dist + 1;                que.push(Node(nowx, nowy, step));                           }        }    }    return -1;}bool GetDist(){    memset(dist, 0, sizeof(dist));    for (int i = 0; i <= tot; i++)    {        for (int j = 0; j < i; j++)        {            dist[i][j] = dist[j][i]=BFS(i,j);//求两个点之间的最短距离            if (dist[i][j] == -1)                return false;        }    }    return true;}int TSP(){    memset(dp, INF, sizeof(dp));    dp[1][0] = 0;    int End = (1 << (tot+1))-1 ;    for (int st = 0; st <= End; st++)    {        for (int i = 0; i <= tot; i++)        {            for (int j = 0; j <= tot; j++)            {                if (i == j)                    continue;                if ((1 << i)&st == 0 || (1 << j)&st == 1)                    continue;                if (dp[st][i] == INF)                    continue;                dp[st | (1 << j)][j] = min(dp[st | (1 << j)][j], dp[st][i] + dist[i][j]);            }        }    }    if (dp[End][0] == INF)        dp[End][0] = -1;    return dp[End][0];}int main() {    while (scanf("%d%d", &n, &m)!=EOF)    {        tot = 0;        for (int i = 1; i <=n; i++)        {            for (int j = 1; j <= m; j++)            {                scanf("%d", &grid[i][j]);                if (i + j == 2)                    continue;                if (grid[i][j] > 0)                    poi[++tot] = Point(i, j);            }        }           if (tot == 0)        {            printf("0\n");            continue;        }        poi[0] = Point(1, 1);        if (grid[1][1] < 0 || !GetDist())        {            printf("-1\n");            continue;        }        printf("%d\n", TSP());    }    return 0;}
原创粉丝点击