hdu3681 PrisonBreak

来源:互联网 发布:mac 移动硬盘绝对路径 编辑:程序博客网 时间:2024/05/18 00:31
一来想用普通BFS实现,无奈超时,怒换思路
遍历所有的点且仅一次,可转化为TSP问题变形
求满足的最小值,显然二分之

推荐一个TSP好的博客,一看就懂                                  点击打开链接



类似题目:  Disney's FastPass hdu4114                          hdu4085 Peach Blossom Spring

Accepted3681296MS2372K


//#pragma comment(linker, "/STACK:102400000,102400000")//HEAD#include <cstdio>#include <ctime>#include <cstdlib>#include <cstring>#include <queue>#include <string>#include <set>#include <stack>#include <map>#include <cmath>#include <vector>#include <iostream>#include <algorithm>using namespace std;//LOOP#define FF(i, a, b) for(int i = (a); i < (b); ++i)#define FE(i, a, b) for(int i = (a); i <= (b); ++i)#define REP(i, N) for(int i = 0; i < (N); ++i)#define CLR(A,value) memset(A,value,sizeof(A))//STL#define PB push_back//INPUT#define RI(n) scanf("%d", &n)#define RII(n, m) scanf("%d%d", &n, &m)#define RIII(n, m, k) scanf("%d%d%d", &n, &m, &k)#define RIV(n, m, k, p) scanf("%d%d%d%d", &n, &m, &k, &p)#define RS(s) scanf("%s", s)//OUTPUT#define WI(n) printf("%d\n", n)#define WS(s) printf("%s\n", s)typedef long long LL;const int INF = 0x3f3f3f3f;const double eps = 1e-10;const int maxn = 16;const LL MOD = 1e9 + 7;const int F = 1, G = 2, Y = 3;int n, m, cnt, sta, all;struct SWITCH{    short int x, y, kind;}sw[maxn];struct node{    short int x, y, step;    node(int a, int b, int s) : x(a), y(b), step(s) {}};char mat[maxn][maxn];int dis[maxn][maxn], dp[maxn][1 << 15], id[maxn][maxn];bool vis[maxn][maxn];int dir[][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};void bfs(int th){    CLR(vis, 0);    queue<node> Q;    vis[sw[th].x][sw[th].y] = 1;    dis[th][th] = 0;    Q.push(node(sw[th].x, sw[th].y, 0));    while (!Q.empty())    {        node t = Q.front(); Q.pop();        REP(i, 4)        {            int x = t.x + dir[i][0], y = t.y + dir[i][1];            if (x < 0 || x >= n || y < 0 || y >= m || mat[x][y] == 'D') continue;            if (!vis[x][y])            {                if (id[x][y] != -1)                    dis[th][id[x][y]] = t.step + 1;                vis[x][y] = 1;                Q.push(node(x, y, t.step + 1));            }        }    }}bool ok(int full, int goal){    CLR(dp, -1);    dp[sta][1 << sta] = full;    REP(s0, all)    {        REP(i, cnt)        {            if (dp[i][s0] == -1)    continue;            if ((s0 & goal) == goal)    return 1;            REP(j, cnt)            {                if (s0 & (1 << j))  continue;                int ns = s0 | (1 << j);                dp[j][ns] = max(dp[j][ns], dp[i][s0] - dis[i][j]);                if (dp[j][ns] >= 0 && sw[j].kind == G)                    dp[j][ns] = full;            }        }    }    return false;}void solve(){    CLR(dis, 0x3f);    int goal = 0;    all = (1 << cnt);    REP(i, cnt)        bfs(i);    REP(i, cnt)        if (sw[i].kind != G)            goal |= (1 << i);    int L = 0, R = n * m * 2;    while (L <= R)    {        int mid = (L + R) >> 1;        if (ok(mid, goal))            R = mid - 1;        else            L = mid + 1;    }    if (L > n * m * 2)        WI(-1);    else        WI(L);}int main(){    while (~RII(n, m), n || m)    {        cnt = 0;        CLR(id, -1);        REP(i, n)        {            RS(mat[i]);            REP(j, m)            {                if (mat[i][j] == 'F')                    id[i][j] = cnt, sta = cnt, sw[cnt].kind = F, sw[cnt].x = i, sw[cnt].y = j, ++cnt;                else if (mat[i][j] == 'G')                    id[i][j] = cnt, sw[cnt].kind = G, sw[cnt].x = i, sw[cnt].y = j, ++cnt;                else if (mat[i][j] == 'Y')                    id[i][j] = cnt, sw[cnt].kind = Y, sw[cnt].x = i, sw[cnt].y = j, ++cnt;            }        }        solve();    }}


DFS版本,只对有用节点进行DFS即可

31ms

//#pragma comment(linker, "/STACK:102400000,102400000")//HEAD#include <cstdio>#include <ctime>#include <cstdlib>#include <cstring>#include <queue>#include <string>#include <set>#include <stack>#include <map>#include <cmath>#include <vector>#include <iostream>#include <algorithm>using namespace std;//LOOP#define FF(i, a, b) for(int i = (a); i < (b); ++i)#define FD(i, b, a) for(int i = (b) - 1; i >= (a); --i)#define FE(i, a, b) for(int i = (a); i <= (b); ++i)#define FED(i, b, a) for(int i = (b); i>= (a); --i)#define REP(i, N) for(int i = 0; i < (N); ++i)#define CLR(A,value) memset(A,value,sizeof(A))#define CPY(a, b) memcpy(a, b, sizeof(a))#define FC(it, c) for(__typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)//STL#define SZ(V) (int)V.size()#define PB push_back#define EQ(a, b) (fabs((a) - (b)) <= 1e-10)#define ALL(c) (c).begin(), (c).end()//INPUT#define RI(n) scanf("%d", &n)#define RII(n, m) scanf("%d%d", &n, &m)#define RIII(n, m, k) scanf("%d%d%d", &n, &m, &k)#define RIV(n, m, k, p) scanf("%d%d%d%d", &n, &m, &k, &p)#define RV(n, m, k, p, q) scanf("%d%d%d%d%d", &n, &m, &k, &p, &q)#define RS(s) scanf("%s", s)//OUTPUT#define WI(n) printf("%d\n", n)#define WS(s) printf("%s\n", s)typedef long long LL;typedef unsigned long long ULL;typedef vector <int> VI;const int INF = 0x3f3f3f3f;const double eps = 1e-10;const int maxn = 16;const LL MOD = 1e9 + 7;const int F = 1, G = 2, Y = 3;int n, m, cnt, sta, all, goal;struct SWITCH{    short int x, y, kind;}sw[maxn];struct node{    short int x, y, step;    node(int a, int b, int s) : x(a), y(b), step(s) {}};char mat[maxn][maxn];int dis[maxn][maxn], dp[maxn][1 << 15], id[maxn][maxn];bool vis[maxn][maxn];int dir[][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};void bfs(int th){    CLR(vis, 0);    queue<node> Q;    vis[sw[th].x][sw[th].y] = 1;    dis[th][th] = 0;    Q.push(node(sw[th].x, sw[th].y, 0));    while (!Q.empty())    {        node t = Q.front(); Q.pop();        REP(i, 4)        {            int x = t.x + dir[i][0], y = t.y + dir[i][1];            if (x < 0 || x >= n || y < 0 || y >= m || mat[x][y] == 'D') continue;            if (!vis[x][y])            {                if (id[x][y] != -1)                    dis[th][id[x][y]] = t.step + 1;                vis[x][y] = 1;                Q.push(node(x, y, t.step + 1));            }        }    }}bool dfs(int u, int s0, int left, int full){    if ((s0 & goal) == goal)    return 1;    REP(v, cnt)        if (left >= dis[u][v])        {            if (s0 & (1 << v))  continue;            if (sw[v].kind == G)            {                if (dfs(v, s0 | (1 << v), full, full))                    return 1;            }            else            {                if (dfs(v, s0 | (1 << v), left - dis[u][v], full))                    return 1;            }        }    return 0;}bool ok(int mid){    return dfs(sta, (1 << sta), mid, mid);}void solve(){    CLR(dis, 0x3f);    goal = 0;    all = (1 << cnt);    REP(i, cnt)        bfs(i);    REP(i, cnt)        if (sw[i].kind == Y && dis[sta][i] == INF)        {            WI(-1);            return;        }    REP(i, cnt)        if (sw[i].kind != G)            goal |= (1 << i);    int L = 0, R = n * m * 2;    while (L <= R)    {        int mid = (L + R) >> 1;        if (ok(mid))            R = mid - 1;        else            L = mid + 1;    }    if (L > n * m * 2)        WI(-1);    else        WI(L);}int main(){    while (~RII(n, m), n || m)    {        cnt = 0;        CLR(id, -1);        REP(i, n)        {            RS(mat[i]);            REP(j, m)            {                if (mat[i][j] == 'F')                    id[i][j] = cnt, sta = cnt, sw[cnt].kind = F, sw[cnt].x = i, sw[cnt].y = j, ++cnt;                else if (mat[i][j] == 'G')                    id[i][j] = cnt, sw[cnt].kind = G, sw[cnt].x = i, sw[cnt].y = j, ++cnt;                else if (mat[i][j] == 'Y')                    id[i][j] = cnt, sw[cnt].kind = Y, sw[cnt].x = i, sw[cnt].y = j, ++cnt;            }        }        solve();    }}



原创粉丝点击