zoukankan      html  css  js  c++  java
  • bfs+状态压缩dp

    题目连接

    题解 : 对两两管道进行bfs,然后用dp[i][j] 来表示在i状态下通过了前j个管道

    参考博客

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef long double db;
    typedef pair<int,int> pii;
    typedef vector<int> vi;
    #define de(x) cout << #x << "=" << x << endl
    #define rep(i,a,b) for(int i=a;i<(b);++i)
    #define all(x) (x).begin(),(x).end()
    #define sz(x) (int)(x).size()
    #define pb push_back
    #define fi first
    #define se second
    const int inf = 0x3f3f3f3f;
    const int N = 1e5+5;
    char mp[20][20];
    struct Pipe{
    	int x1,x2,y1,y2;
    }a[20];
    int dx[4]={1,0,-1,0};
    int dy[4]={0,1,0,-1};
    int dis[20][20];
    int pp[20][20];
    int dp[1<<15][20];
    int n,m;
    int bfs(Pipe a,Pipe b)
    {
    	queue<pii>que;
    	int nx,ny;
    	memset(dis,-1,sizeof(dis));
    	dis[a.x2][a.y2]=0;
    	que.push(pii(a.x2,a.y2));
    	while(!que.empty())
    	{
    		pii u=que.front();
    		que.pop();
    		if(u.fi==b.x1&&u.se==b.y1) return dis[u.fi][u.se];
    		for(int i=0;i<4;i++)
    		{
    			nx=u.fi+dx[i],ny=u.se+dy[i];
    			if(nx>n||nx<=0||ny>n||ny<=0||mp[nx][ny]=='#'||dis[nx][ny]!=-1) continue;
    			dis[nx][ny]=dis[u.fi][u.se]+1;
    			que.push(pii(nx,ny));
    		}
    	}
    	return -1;
    }
    void init()
    {
    	for(int i=1;i<=m;i++)
    	{
    		for(int j=1;j<=m;j++)
    		{
    			if(i==j) pp[i][j]=0;
    			else pp[i][j]=bfs(a[i],a[j]);
    		}
    	}
    }
    
    int main()
    {
    	while(~scanf("%d%d",&n,&m))
    	{
    		for(int i=1;i<=n;i++)
    			scanf("%s",mp[i]+1);
    		for(int i=1;i<=m;i++)
    		{
    			scanf("%d%d%d%d",&a[i].x1,&a[i].y1,&a[i].x2,&a[i].y2);
    		}
    		init();
    		memset(dp,inf,sizeof(dp));
    		for(int i=1;i<=m;i++)
    		{
    			dp[1<<(i-1)][i]=0;
    		}
    		int ans=inf;
    		for(int i=0;i<(1<<m);i++)
    		{
    			for(int j=1;j<=m;j++)
    			{
    				if(i&(1<<(j-1)))//i状态下有第j个管道才能进行
    				{
    					for(int k=1;k<=m;k++)
    					{
    						if(i&(1<<(k-1))==0||pp[k][j]==-1) continue;//同理
    						dp[i][j]=min(dp[i^(1<<(j-1))][k]+pp[k][j],dp[i][j]);
    					}	
    				}
    				if(i==(1<<m)-1) ans=min(ans,dp[i][j]);
    			}
    		}
    		if(ans==inf) cout<<"-1
    ";
    		else cout<<ans<<endl;
    	}
    }
    
  • 相关阅读:
    SQLSERVER 分区分表
    SQLSERVER 执行计划
    SQL SERVER 自定义函数
    codeforces 414C C. Mashmokh and Reverse Operation(归并排序求逆序对)
    codeforces 414A A. Mashmokh and Numbers(素数筛)
    codeforces 414B B. Mashmokh and ACM(dp)
    bzoj-1012 1012: [JSOI2008]最大数maxnumber(线段树)
    codeforces 665E E. Beautiful Subarrays(trie树)
    codeforces 667D D. World Tour(最短路)
    codeforces 667C C. Reberland Linguistics(dp)
  • 原文地址:https://www.cnblogs.com/q1076452761/p/7689195.html
Copyright © 2011-2022 走看看