第一行有兩個整數,N和 M,描述方塊的數目。
接下來 N行, 每行有 M 個非負整數, 若是該整數爲 0, 則該方塊爲一個景點;
不然表示控制該方塊至少須要的志願者數目。 相鄰的整數用 (若干個) 空格隔開,
行首行末也可能有多餘的空格。php
由 N + 1行組成。第一行爲一個整數,表示你所給出的方案中安排的志願者總數目。
接下來 N行,每行M 個字符,描述方案中相應方塊的狀況:
z ‘_’(下劃線)表示該方塊沒有安排志願者;
z ‘o’(小寫英文字母o)表示該方塊安排了志願者;
z ‘x’(小寫英文字母x)表示該方塊是一個景點;
注:請注意輸出格式要求,若是缺乏某一行或者某一行的字符數目和要求不
一致(任何一行中,多餘的空格都不容許出現) ,均可能致使該測試點不得分。ios
對於100%的數據,N,M,K≤10,其中K爲景點的數目。輸入的全部整數均在[0,2^16]的範圍內測試
Ljcc930提供SPJ spa
如今就是留下板子走人= =blog
狀壓dp+spfa鬆弛一下就能夠了。ip
本身寫個破爛模板還要調一會= =,寫完後發現網上絕大部分的人都是三個數壓起來,只有我弱智的記下來。ci
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<cmath> #include<queue> using namespace std; #define INF 0xf0f0f0f #define Pa pair<int,int> #define PPa pair<Pa,int> #define fi first #define se second #define MP make_pair Pa nidx[150]; PPa nidp[250000]; int N,S,M,mp[11][11],bin[11][11]; int idx[11][11],idp[11][11][1<<10],dp[11][11][1<<10],fr[11][11][1<<10]; inline void Update(int nx,int ny,int nz,int ox,int oy,int oz,int z) { if (dp[nx][ny][nz]>z) dp[nx][ny][nz]=z,fr[nx][ny][nz]=idp[ox][oy][oz]; } int dx[4]={1,-1,0,0},dy[4]={0,0,1,-1},visit[150]; queue<int>q; inline void Spfa(int sta) { while (!q.empty()) { int now=q.front(); visit[now]=0; q.pop(); int x=nidx[now].fi,y=nidx[now].se; for (int d=0; d<4; d++) { int tx=x+dx[d],ty=y+dy[d]; if (!tx || !ty || tx>N || ty>M) continue; if (dp[tx][ty][sta]>dp[x][y][sta]+mp[tx][ty]) { Update(tx,ty,sta,x,y,sta,dp[x][y][sta]+mp[tx][ty]); if (!visit[idx[tx][ty]]) q.push(idx[tx][ty]),visit[idx[tx][ty]]=1; } } } } bool mark[11][11]; inline void Dfs(int x,int y,int sta) { if (!fr[x][y][sta]) return; mark[x][y]=1; int now=fr[x][y][sta]; int tx=nidp[now].fi.fi,ty=nidp[now].fi.se,ts=nidp[now].se; Dfs(tx,ty,ts); if (tx==x && ty==y) Dfs(tx,ty,sta-ts); } int main() { memset(dp,0xf,sizeof(dp)); scanf("%d%d",&N,&M); for (int i=1; i<=N; i++) for (int j=1; j<=M; j++) { scanf("%d",&mp[i][j]); if (!mp[i][j]) bin[i][j]=1<<(S++),dp[i][j][bin[i][j]]=0; } for (int i=1,Idx=0,Idp=0; i<=N; i++) for (int j=1; j<=M; j++) { idx[i][j]=++Idx; nidx[Idx]=MP(i,j); for (int k=0; k<(1<<S); k++) idp[i][j][k]=++Idp,nidp[Idp]=MP(MP(i,j),k); } for (int k=1; k<(1<<S); k++) { for (int i=1; i<=N; i++) { for (int j=1; j<=M; j++) { for (int s=k&(k-1); s; s=(s-1)&k) Update(i,j,k,i,j,s,dp[i][j][s]+dp[i][j][k-s]-mp[i][j]); if (dp[i][j][k]!=INF) q.push(idx[i][j]),visit[idx[i][j]]=1; } } Spfa(k); } for (int i=1; i<=N; i++) { for (int j=1; j<=M; j++) if (!mp[i][j]) { printf("%d\n",dp[i][j][(1<<S)-1]); Dfs(i,j,(1<<S)-1); for (int x=1; x<=N; x++,puts("")) for (int y=1; y<=M; y++) { if (!mp[x][y]) printf("x"); else if (mark[x][y]) printf("o"); else printf("_"); } return 0; } } return 0; }