2 条题解
-
0
#include <bits/stdc++.h> #define int long long using namespace std; typedef pair<int, int> PII; int a[15][15], p[15], dp[105][5000], pre[105][5000]; bool ans[15][15][5000], an[15][15]; vector<PII> e[105];//e[i].second 是没用的但我懒得改了反正空间管够 int n, m, k; int number(int x, int y) { return (x-1)*m + y - 1; } PII enc(int p) { int x = p/m + 1, y = p%m + 1; return {x, y}; } bool vis[105]; int val[105]; void dij(int S) { memset(vis, 0, sizeof(vis)); priority_queue<PII, vector<PII>, greater<PII>> q; for(int i = number(1, 1); i <= number(n, m); i++) if(dp[i][S] != 0x3f3f3f3f) q.push({dp[i][S], i}); while(!q.empty()) { int x = q.top().second; q.pop(); if(vis[x]) continue; for(PII t : e[x]) { int y = t.first, w = t.second; if(dp[y][S] > dp[x][S] + val[y]) { dp[y][S] = dp[x][S] + val[y]; pre[y][S] = x; q.push({dp[y][S], y}); } } } } void road(int q, int S) { PII p = enc(q); int x = p.first, y = p.second; if(ans[x][y][S]) return; ans[x][y][S] = 1; an[x][y] = 1; if(pre[q][S] != -1 && dp[pre[q][S]][S] + val[q] == dp[q][S]) { road(pre[q][S], S); } for(int s = S; s; s = ((s-1) & S)) { if(dp[q][S] == dp[q][s] + dp[q][S^s] - val[q]) { road(q, s); road(q, S^s); break; } } } signed main() { ios::sync_with_stdio(0); cin.tie(0); cin >> n >> m; for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) { cin >> a[i][j]; } memset(dp, 0x3f, sizeof(dp)); memset(pre, -1, sizeof(pre)); for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) { if(i > 1) e[number(i, j)].push_back({number(i-1, j), a[i-1][j]}); if(i < n) e[number(i, j)].push_back({number(i+1, j), a[i+1][j]}); if(j > 1) e[number(i, j)].push_back({number(i, j-1), a[i][j-1]}); if(j < m) e[number(i, j)].push_back({number(i, j+1), a[i][j+1]}); if(a[i][j] == 0) { p[++k] = number(i, j); dp[number(i, j)][1 << k-1] = 0; } val[number(i, j)] = a[i][j]; } for(int S = 0; S < (1 << k); S++) { for(int s = S; s; s = ((s-1) & S)) { for(int i = number(1, 1); i <= number(n, m); i++) { dp[i][S] = min(dp[i][S], dp[i][s] + dp[i][S^s] - val[i]); } } dij(S); } if(k == 0) cout << 0 << endl; else cout << dp[p[1]][(1 << k)-1] << endl; if(k) road(p[1], (1 << k)-1); for(int i = 1; i <= n; i++) { for(int j = 1; j <= m; j++) { if(a[i][j]) if(an[i][j]) cout << 'o'; else cout << '_'; else cout << 'x'; } cout << endl; } return 0; } -
0
#include<bits/stdc++.h> #define int long long using namespace std; typedef pair<int,int> PII; int a[15][15],p[15],dp[105][5000],pre[105][5000]; bool ans[15][15][5000],an[15][15]; vector<PII>e[105];//e[i].second 是没用的但我懒得改了反正空间管够 int n,m,k; int number(int x,int y){ return (x-1)*m+y-1; } PII enc(int p){ int x=p/m+1,y=p%m+1; return {x,y}; } bool vis[105]; int val[105]; void dij(int S){ memset(vis,0,sizeof(vis)); priority_queue<PII,vector<PII>,greater<PII>>q; for(int i=number(1,1);i<=number(n,m);i++)if(dp[i][S]!=0x3f3f3f3f)q.push({dp[i][S],i}); while(!q.empty()){ int x=q.top().second;q.pop(); if(vis[x])continue; for(PII t:e[x]){ int y=t.first,w=t.second; if(dp[y][S]>dp[x][S]+val[y]){ dp[y][S]=dp[x][S]+val[y]; pre[y][S]=x; q.push({dp[y][S],y}); } } } } void road(int q,int S){ PII p=enc(q); int x=p.first,y=p.second; if(ans[x][y][S])return; ans[x][y][S]=1; an[x][y]=1; if(pre[q][S]!=-1&&dp[pre[q][S]][S]+val[q]==dp[q][S]){ road(pre[q][S],S); } for(int s=S;s;s=((s-1)&S)){ if(dp[q][S]==dp[q][s]+dp[q][S^s]-val[q]){ road(q,s);road(q,S^s); break; } } } signed main(){ ios::sync_with_stdio(0);cin.tie(0); cin>>n>>m; for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){ cin>>a[i][j]; } memset(dp,0x3f,sizeof(dp)); memset(pre,-1,sizeof(pre)); for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){ if(i>1)e[number(i,j)].push_back({number(i-1,j),a[i-1][j]}); if(i<n)e[number(i,j)].push_back({number(i+1,j),a[i+1][j]}); if(j>1)e[number(i,j)].push_back({number(i,j-1),a[i][j-1]}); if(j<m)e[number(i,j)].push_back({number(i,j+1),a[i][j+1]}); if(a[i][j]==0){ p[++k]=number(i,j); dp[number(i,j)][1<<k-1]=0; }val[(number(i,j))]=a[i][j]; } for(int S=0;S<(1<<k);S++){ for(int s=S;s;s=((s-1)&S)){ for(int i=number(1,1);i<=number(n,m);i++){ dp[i][S]=min(dp[i][S],dp[i][s]+dp[i][S^s]-val[i]); } } dij(S); } if(k==0)cout<<0<<endl; else cout<<dp[p[1]][(1<<k)-1]<<endl; if(k)road(p[1],(1<<k)-1); for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ if(a[i][j]) if(an[i][j])cout<<'o'; else cout<<'_'; else cout<<'x'; } cout<<endl; } return 0; }
- 1
信息
- ID
- 7409
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 8
- 标签
- 递交数
- 25
- 已通过
- 5
- 上传者