1 条题解

  • 0
    @ 2025-10-8 17:07:49

    by_OctoberEstuary:

    #include<bits/stdc++.h>
    using namespace std;
    const int inf = 0x3f3f3f3f;
    template <typename Tp>
    void chmin(Tp &x, const Tp &y){ if(x > y) x = y; }
    const int F[4]={0,-1,0,1};
    const int G[4]={-1,0,1,0};

    int n,m,k,ans=inf; char a[505][505];

    int gx[4][505][505],gy[4][505][505],inq[4][505][505]; void work(int x, int y, int z){ if(gx[z][x][y] || gy[z][x][y]) return; if(x<1 || x>n || y<1 || y>m || a[x][y]=='x'){ gx[z][x][y] = gy[z][x][y] = -1; return; } if(inq[z][x][y]){ gx[z][x][y] = gy[z][x][y] = -2; return; } inq[z][x][y] = 1;

    int u&#44; v&#44; w=z;
    if(a[x][y] == 'A') (w += 3) &amp;= 3;
    if(a[x][y] == 'C') (w += 1) &amp;= 3;
    u = x + F[w]; v = y + G[w];
    
    work(u&#44; v&#44; w);
    gx[z][x][y] = gx[w][ u ][v]; gy[z][x][y] = gy[w][ u ][v];
    if(gx[z][x][y] == -1){
    	gx[z][x][y] = x; gy[z][x][y] = y;
    }
    inq[z][x][y] = 0;
    return;
    

    }

    int f[10][10][505][505],L,R; pair<int,int> qa[250005]; priority_queue<pair<int,pair<int,int> > > qb; int vis[505][505],ql,qr; bool cmp(pair<int,int> x, pair<int,int> y){ return f[L][R][x.first][x.second] < f[L][R][y.first][y.second]; } void dij(){ int l=L, r=R; memset(vis, 0, sizeof(vis)); ql=1; qr=0; for(int i=1; i<=n; i++)for(int j=1; j<=m; j++)if(f[l][r][i][j] < inf){ qa[++qr] = make_pair(i,j); } stable_sort(qa+1, qa+qr+1, cmp); int x,y,u,v; while(!qb.empty() || ql<=qr){ if(ql<=qr && qb.empty()){ tie(x,y) = qa[ql++]; } else if(ql>qr && !qb.empty()){ tie(x,y) = qb.top().second; qb.pop(); } else if(cmp(qa[ql], qb.top().second)){ tie(x,y) = qa[ql++]; } else { tie(x,y) = qb.top().second; qb.pop(); }

    	if(vis[x][y]) continue;
    	vis[x][y] = 1;
    	
    	for(int i=0; i&lt;4; i++)if(gx[i][x][y] &gt; 0){
    		u = gx[i][x][y];
    		v = gy[i][x][y];
    		if(f[l][r][ u ][v] &gt; f[l][r][x][y] + 1){
    			f[l][r][ u ][v] = f[l][r][x][y] + 1;
    			qb.emplace(-f[l][r][ u ][v]&#44; make_pair(u&#44;v));
    		}
    	}
    }
    

    }

    int main(){ scanf("%d%d%d",&k,&m,&n); for(int i=1; i<=n; i++) scanf("%s",a[i]+1);

    for(int i=1; i&lt;=n; i++)for(int j=1; j&lt;=m; j++){
    	work(i&#44; j&#44; 0);
    	work(i&#44; j&#44; 1);
    	work(i&#44; j&#44; 2);
    	work(i&#44; j&#44; 3);
    }
    
    memset(f&#44; 0x3f&#44; sizeof(f));
    for(int i=1; i&lt;=n; i++)for(int j=1; j&lt;=m; j++)if(isdigit(a[i][j])){
    	f[a[i][j]-'0'][a[i][j]-'0'][i][j] = 0;
    }
    
    for(int i=1; i&lt;=k; i++){
    	for(int l=1&#44;r=i; r&lt;=k; l++&#44;r++){
    		for(int d=l; d&lt;r; d++){
    			for(int u=1; u&lt;=n; u++)for(int v=1; v&lt;=m; v++){
    				chmin(f[l][r][ u ][v]&#44; f[l][d][ u ][v] + f[d+1][r][ u ][v]);
    			}
    		}
    		L=l; R=r;
    		dij();
    	}
    }
    
    for(int i=1; i&lt;=n; i++)for(int j=1; j&lt;=m; j++) chmin(ans&#44; f[1][k][i][j]);
    (ans==inf) ? printf("-1") : printf("%d"&#44;ans);
    return 0;
    

    } /* 0: L 1: U 2: R 3: D */</pre>

    • 1

    【状压DP:最小斯坦纳树】 [APIO2013] 机器人

    信息

    ID
    4870
    时间
    1500ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    5
    已通过
    1
    上传者