codeforces 152E bfs+状态压缩
来源:互联网 发布:男生暗恋女生知乎 编辑:程序博客网 时间:2024/04/29 20:22
/*题意:在一些n*m的网格中 每个格子里面都有一些不同数量的花 问现在要使得一些给定的重要位置联通 你需要破坏至少多少花来使得道路联通*//* 我们采用暴力的思维 把重要位置当成状态来处理 然后枚举出发的位置点 取最优结果就ok啦*/#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>#include<algorithm>#include<sstream>#include<cmath>#include<queue>#include<stack>#include<map>#include<set>#include<vector>using namespace std;typedef long long ll;#define inf 1<<29#define eps 1e-10#define maxl 210#define mem(i,j) memset(i,j,sizeof(i))int dp[maxl][1<<7],pre[maxl][1<<7];//状态压缩 dp表示从网格中某个格子出发访问过某几个所需要的最小花费int n,m,k,nn,mm;int hash1[maxl];int maz[maxl][maxl];//初始值char g[maxl][maxl];//保存结果bool visit[maxl][1<<7];int dx[]= {0,0,-1,1};int dy[]= {-1,1,0,0};struct Node{ int u,st; Node(int _u,int _st) { u=_u,st=_st; }};queue<Node> que;bool check(int x,int y){ if(x>=0&&x<n&&y>=0&&y<m) return true; return false;}void update(int u,int st,int w,int fa){ if(dp[u][st]>w)//累计和 { dp[u][st]=w; pre[u][st]=fa; if(!visit[u][st]) { que.push(Node(u,st)); visit[u][st]=true; } }}void dfs(int u,int st){ int x=u/m,y=u%m; g[x][y]='X'; if(pre[u][st]==-1) return ; else { int v=pre[u][st]/1000,stt=pre[u][st]%1000; dfs(v,stt); if(stt-st) dfs(v,st-stt); }}void solve(){ while(!que.empty()) { Node now=que.front(); que.pop(); int u=now.u,x=now.u/m,y=now.u%m,st=now.st;//取出得到对应行列 visit[u][st]=false; for(int i=0; i<4; i++) { int xx=x+dx[i],yy=dy[i]+y; if(!check(xx,yy)) continue; int v=xx*m+yy; update(v,st,dp[u][st]+maz[xx][yy],u*1000+st);//向四周扩展 } //这部分是最关键的 int t=mm-1-st; for(int i=t; i; i=(i-1)&t)//i指的就是取另外与st无交集的另外一些 { update(u,i|st,dp[u][i]+dp[u][st]-maz[x][y],u*1000+st);//注意这里减去重复的部分 因为是从st 这个点的位置出发走了俩次 所以减去 } } int ans=inf,u; for(int i=0; i<nn; i++) if(ans>dp[i][mm-1])//mm-1表示全部访问完成 看从图上的那个格子出发取的最小 { ans=dp[i][mm-1]; u=i; } dfs(u,mm-1); cout<<ans<<endl; for(int i=0; i<n; i++) { for(int j=0; j<m; j++) cout<<g[i][j]; cout<<endl; }}int main(){ freopen("in.txt", "r", stdin); while(cin>>n>>m>>k) { for(int i=0; i<n; i++) for(int j=0; j<m; j++) { cin>>maz[i][j]; g[i][j]='.'; } nn=n*m; mm=1<<k; memset(hash1,0,sizeof(hash1)); memset(visit,false,sizeof(visit)); for(int i=0; i<nn; i++) for(int j=0; j<mm; j++) dp[i][j]=inf; for(int i=0,a,b; i<k; i++) { cin>>a>>b; a--,b--; int u=a*m+b; hash1[u]=1<<i; update(u,hash1[u],maz[a][b],-1); } solve(); }}
0 0
- codeforces 152E bfs+状态压缩
- codeforces 165E 状态压缩
- codeforces 152E Garden(状态压缩dp)
- E. Fish+状态压缩dp+codeforces
- CodeForces 197D Infinite Maze (BFS+状态压缩)
- codeforces GYM 101431E (状态压缩dp+博弈)
- BFS+状态压缩 HDU1429
- hdu1429(BFS+状态压缩)
- 状态压缩+bfs
- HDU_4856_Tunnels(BFS+状态压缩)
- bfs+状态压缩dp
- hdu1429 状态压缩+bfs
- [poj1324]状态压缩+BFS
- 状态压缩+bfs
- hdu4845 状态压缩BFS
- hdu5025(bfs + 状态压缩)
- hdu5094Maze bfs+状态压缩
- 某校赛题(bfs+状态压缩)
- 《计算机网络》总结
- HTTP 文件下载时中文文件名乱码问题处理
- linux安装包制作
- 查看Ubuntu系统信息方面的命令
- iOS开发:界面传值之Block传值
- codeforces 152E bfs+状态压缩
- Android动态换肤开源库Colorful发布
- 业界大牛级程序员给程序员的一些建议
- Storm实时分布式计算系统简介
- 数据结构中的二叉树
- Redis - 02. 配置Redis
- SessionState的配置(web.config)
- java 泛型
- Data Binding官方用户指南