日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

POJ2688状态压缩(可以+DFS剪枝)

發布時間:2025/6/17 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 POJ2688状态压缩(可以+DFS剪枝) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題意:
? ? ? 給你一個n*m的格子,然后給你一個起點,讓你遍歷所有的垃圾,就是終點不唯一,問你最小路徑是多少?


思路:
? ? ? 水題,方法比較多,最省事的就是直接就一個BFS狀態壓縮暴搜就行了,時間復雜度20*20*1024的,完全可以接受,但是被坑了,一開始怎么交都TLE,后來又寫了一個BFS+DFS優化,就是跑之前先遍歷一遍圖,看看是不是所有的垃圾點都能遍歷到,這樣還是超時,無奈看了下討論,有人說用G++交就行了,我用G++交了結果兩個方法都AC了,哎!下面是兩個方法的代碼,比較簡單,最近就是無聊,上POJ來刷刷水題,還有這個題目,可以用DP去做,還有就是可以直接求出任意兩個垃圾的最短距離,然后在枚舉處理垃圾順序,枚舉可以用STL的全排列,也可以搜索,這樣的時間復雜度大約是N!吧,跟直接暴搜沒啥區別,想試的可以敲敲試試吧。




直接BFS狀態壓縮暴力625
#include<queue>
#include<stdio.h>
#include<string.h>


using namespace std;


typedef struct
{
? ? int x ,y ,k ,t;
}NODE;


NODE xin ,tou;
int map[22][22] ,n ,m ,w;
int mark[22][22][1025];
int dir[4][2] = {0 ,1 ,0 ,-1 ,1 ,0 ,-1 ,0};


bool ok(int x ,int y ,int k)
{
? ? return x >= 1 && x <= n && y >= 1 && y <= m && map[x][y] && !mark[x][y][k];
}


int BFS(int x ,int y)
{
? ? queue<NODE>q;
? ? xin.x = x ,xin.y = y;
? ? xin.t = 0 ,xin.k = 0;
? ? memset(mark ,0 ,sizeof(mark));
? ? mark[xin.x][xin.y][xin.k] = 1;
? ? q.push(xin);
? ? while(!q.empty())
? ? {
? ? ? ? tou = q.front();
? ? ? ? q.pop();
? ? ? ? for(int i = 0 ;i < 4 ;i ++)
? ? ? ? {
? ? ? ? ? ? xin.x = tou.x + dir[i][0];
? ? ? ? ? ? xin.y = tou.y + dir[i][1];
? ? ? ? ? ? xin.t = tou.t + 1;
? ? ? ? ? ? if(map[xin.x][xin.y] && map[xin.x][xin.y] != -1)
? ? ? ? ? ? xin.k = tou.k | (1 << (map[xin.x][xin.y] - 1));
? ? ? ? ? ? else xin.k = tou.k;
? ? ? ? ? ? if(ok(xin.x ,xin.y ,xin.k))
? ? ? ? ? ? {
? ? ? ? ? ? ? ? mark[xin.x][xin.y][xin.k] = 1;
? ? ? ? ? ? ? ? q.push(xin);
? ? ? ? ? ? ? ? if(xin.k == (1 << w) - 1) return xin.t;
? ? ? ? ? ? }
? ? ? ? }
? ? }
? ? return -1;
}




int main ()
{
? ? char str[22];
? ? int x ,y;
? ? while(~scanf("%d %d" ,&m ,&n) && n+m)
? ? {
? ? ? ? w = 0;
? ? ? ? for(int i = 1 ;i <= n ;i ++)
? ? ? ? {
? ? ? ? ? ? scanf("%s" ,str);
? ? ? ? ? ? for(int j = 1 ;j <= m ;j ++)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? if(str[j-1] == '.') map[i][j] = -1;
? ? ? ? ? ? ? ? else if(str[j-1] == '*') map[i][j] = ++w;
? ? ? ? ? ? ? ? else if(str[j-1] == 'x') map[i][j] = 0;
? ? ? ? ? ? ? ? else x = i ,y = j ,map[i][j] = -1;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? w ? printf("%d\n" ,BFS(x ,y)):printf("0\n");
? ? }
? ? return 0;
}






BFS+DFS剪枝594
#include<queue>
#include<stdio.h>
#include<string.h>


using namespace std;


typedef struct
{
? ? int x ,y ,k ,t;
}NODE;


NODE xin ,tou;
int col[22][22] ,cmk[22][22];
int map[22][22] ,n ,m ,w;
int mark[22][22][1025];
int dir[4][2] = {0 ,1 ,0 ,-1 ,1 ,0 ,-1 ,0};


bool ok(int x ,int y ,int k)
{
? ? return x >= 1 && x <= n && y >= 1 && y <= m && map[x][y] && !mark[x][y][k];
}


int BFS(int x ,int y)
{
? ? queue<NODE>q;
? ? xin.x = x ,xin.y = y;
? ? xin.t = 0 ,xin.k = 0;
? ? memset(mark ,0 ,sizeof(mark));
? ? mark[xin.x][xin.y][xin.k] = 1;
? ? q.push(xin);
? ? while(!q.empty())
? ? {
? ? ? ? tou = q.front();
? ? ? ? q.pop();
? ? ? ? for(int i = 0 ;i < 4 ;i ++)
? ? ? ? {
? ? ? ? ? ? xin.x = tou.x + dir[i][0];
? ? ? ? ? ? xin.y = tou.y + dir[i][1];
? ? ? ? ? ? xin.t = tou.t + 1;
? ? ? ? ? ? if(map[xin.x][xin.y] && map[xin.x][xin.y] != -1)
? ? ? ? ? ? xin.k = tou.k | (1 << (map[xin.x][xin.y] - 1));
? ? ? ? ? ? else xin.k = tou.k;
? ? ? ? ? ? if(ok(xin.x ,xin.y ,xin.k))
? ? ? ? ? ? {
? ? ? ? ? ? ? ? mark[xin.x][xin.y][xin.k] = 1;
? ? ? ? ? ? ? ? q.push(xin);
? ? ? ? ? ? ? ? if(xin.k == (1 << w) - 1) return xin.t;
? ? ? ? ? ? }
? ? ? ? }
? ? }
? ? return -1;
}


void DFS(int x ,int y)
{
? ? for(int i = 0 ;i < 4 ;i ++)
? ? {
? ? ? ? int xx = x + dir[i][0];
? ? ? ? int yy = y + dir[i][1];
? ? ? ? if(xx >= 1 && xx <= n && yy >= 1 && yy <= m && !cmk[xx][yy] && map[xx][yy])
? ? ? ? {
? ? ? ? ? ? cmk[xx][yy] = 1;
? ? ? ? ? ? DFS(xx ,yy);
? ? ? ? }
? ? }
}


int main ()
{
? ? char str[22];
? ? int x ,y;
? ? while(~scanf("%d %d" ,&m ,&n) && n+m)
? ? {
? ? ? ? w = 0;
? ? ? ? for(int i = 1 ;i <= n ;i ++)
? ? ? ? {
? ? ? ? ? ? scanf("%s" ,str);
? ? ? ? ? ? for(int j = 1 ;j <= m ;j ++)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? if(str[j-1] == '.') map[i][j] = -1;
? ? ? ? ? ? ? ? else if(str[j-1] == '*') map[i][j] = ++w;
? ? ? ? ? ? ? ? else if(str[j-1] == 'x') map[i][j] = 0;
? ? ? ? ? ? ? ? else x = i ,y = j ,map[i][j] = -1;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? memset(cmk ,0 ,sizeof(cmk));
? ? ? ? DFS(x ,y);
? ? ? ? int mk = 0;
? ? ? ? for(int i = 1 ;i <= n && !mk;i ++)
? ? ? ? for(int j = 1 ;j <= m && !mk;j ++)
? ? ? ? if(map[i][j] != -1 && map[i][j] && !cmk[i][j])
? ? ? ? mk = 1;
? ? ? ? if(mk)
? ? ? ? {
? ? ? ? ? ? printf("-1\n");
? ? ? ? ? ? continue;
? ? ? ? }


? ? ? ? w ? printf("%d\n" ,BFS(x ,y)):printf("0\n");
? ? }
? ? return 0;
}













總結

以上是生活随笔為你收集整理的POJ2688状态压缩(可以+DFS剪枝)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。