1 条题解
-
1
#include <cstdio> #include <iostream> #include <cstring> #include <queue> #include <algorithm> #define ll long long using std::min; using std::vector; using std::priority_queue; using std::pair; using std::sort; typedef pair<int, int> pad; const int MAXN =5e2+5, MAXK =55; namespace IO_base{ const int MAXB =1<<10; char gbuf[MAXB], *ps =gbuf, *pt =gbuf; char _getchar(){ if(ps == pt) ps =gbuf, pt =gbuf+fread(gbuf, 1, MAXB, stdin); return (ps == pt) ? EOF : *ps++; } } #define getchar IO_base::_getchar namespace IO_number{ int read(){ int x =0; bool f =0; char c =getchar(); while(c < '0' || c > '9') ((c == '-') ? f =1 : 0), c =getchar(); while(c >= '0' && c <= '9') x =(x<<1)+(x<<3)+(48^c), c =getchar(); return (f) ? -x : x; } } using namespace IO_number; namespace Dijkstra{ namespace Graph{ struct edge{ int to, w, nxt; }e[MAXN*MAXN*4]; int first[MAXN*MAXN], tote; inline void addedge(const int &u, const int &v, const int &w){ ++tote, e[tote].to =v, e[tote].w =w, e[tote].nxt =first[u], first[u] =tote; ++tote, e[tote].to =u, e[tote].w =w, e[tote].nxt =first[v], first[v] =tote; } int rem_first[MAXN*4*3*2], rem_first_id[MAXN*4*3*2], tot_rem; inline void addedge_(const int &u, const int &v, const int &w){ rem_first[tot_rem] =first[u], rem_first_id[tot_rem] =u, ++tot_rem; ++tote, e[tote].to =v, e[tote].w =w, e[tote].nxt =first[u], first[u] =tote; } void back(){ tote -=tot_rem; while(tot_rem){ --tot_rem; first[rem_first_id[tot_rem]] =rem_first[tot_rem]; } } } using namespace Graph; bool vis[MAXN*MAXN]; int dist[MAXN*MAXN]; void dijkstra(const int &s){ memset(vis, 0, sizeof(vis)); memset(dist, 0x3f, sizeof(dist)); dist[s] =0; priority_queue<pad, vector<pad>, std::greater<pad> > q; q.push(pad(0, s)); while(!q.empty()){ pad cur =q.top(); q.pop(); if(vis[cur.second]) continue; vis[cur.second] =1; for(int l =first[cur.second]; l; l =e[l].nxt) if(!vis[e[l].to] && dist[cur.second]+e[l].w < dist[e[l].to]) q.push(pad(dist[e[l].to] =dist[cur.second]+e[l].w, e[l].to)); } } } using namespace Dijkstra; struct Node{ int w, p, t; }node[MAXK]; int main(){ // freopen("traffic.in", "r", stdin); // freopen("traffic.out", "w", stdout); const int n =read(), m =read(), T =read(); int e1[MAXN][MAXN], e2[MAXN][MAXN]; // 对偶图 x 行 y 列的格子对应的点编号 ( 且相比原来的网格在外围加了一圈格子 ) // auto get_id =[&](const int &x, const int &y){ return x*(m+1)+y; }; for(int i =0; i < n-1; ++i) for(int j =0; j < m; ++j){ e1[i][j] =read(); addedge(get_id(i+1, j), get_id(i+1, j+1), e1[i][j]); } for(int i =0; i < n; ++i) for(int j =0; j < m-1; ++j){ e2[i][j] =read(); addedge(get_id(i, j+1), get_id(i+1, j+1), e2[i][j]); } int id[4*MAXN]; // 射线 i 顺时针下一个无界面对应的结点编号 // for(int i =1; i <= m; ++i) id[i] =get_id(0, i); for(int i =m+1; i <= m+n; ++i) id[i] =get_id(i-m, m); for(int i =m+n+1; i <= 2*m+n; ++i) id[i] =get_id(n, m-(i-m-n)); for(int i =2*m+n+1; i <= 2*m+2*n; ++i) id[i] =get_id(n-(i-2*m-n), 0); for(int _t =0; _t < T; ++_t){ const int ki =read(); for(int i =0; i < ki; ++i) node[i].w =read(), node[i].p =read(), node[i].t =read(); sort(node, node+ki, [&](const Node &A, const Node &B){ return A.p < B.p; }); int v[MAXK<<1], tot_v =0, dist_node[MAXK][MAXK]; node[ki] =node[0]; for(int i =0, new_node =(m+1)*(n+1); i < ki; ++i){ for(int j =node[i].p; j != node[i+1].p; j =(j-1+1)%(2*m+2*n)+1) addedge_(new_node, id[j], 0), addedge_(id[j], new_node, 0); if(i+1 < ki) addedge_(new_node, new_node+1, node[i+1].w), addedge_(new_node+1, new_node, node[i+1].w); else addedge_(new_node, (m+1)*(n+1), node[i+1].w), addedge_((m+1)*(n+1), new_node, node[i+1].w); if(node[i].t != node[i+1].t) v[tot_v++] =new_node; ++new_node; } if(tot_v == 1){ puts("0"); continue; } for(int i =0; i < tot_v; ++i){ dijkstra(v[i]); for(int j =0; j < tot_v; ++j) dist_node[v[i]-(m+1)*(n+1)][v[j]-(m+1)*(n+1)] =Dijkstra::dist[v[j]]; } auto get_dist =[&](const int &A, const int &B){ return dist_node[A-(m+1)*(n+1)][B-(m+1)*(n+1)]; }; ll f[MAXK<<1][MAXK<<1]; memset(f, 0x3f, sizeof(f)); for(int i =0; i < tot_v; ++i) v[i+tot_v] =v[i]; for(int l =0; l+1 < tot_v*2; ++l) f[l][l+1] =get_dist(v[l], v[l+1]); for(int len =4; len <= tot_v; len +=2) for(int l =0; l+len-1 < tot_v*2; ++l){ const int r =l+len-1; f[l][r] =f[l+1][r-1]+get_dist(v[l], v[r]); for(int j =l+1; j <= r-2; j +=2) f[l][r] =min(f[l][r], f[l][j]+f[j+1][r]); } ll ans =0x3f3f3f3f3f3f3f3fll; for(int l =0; l+tot_v-1 < tot_v*2; ++l) ans =min(ans, f[l][l+tot_v-1]); printf("%lld\n", ans); Dijkstra::back(); } return 0; }
- 1
信息
- ID
- 192
- 时间
- 3000ms
- 内存
- 512MiB
- 难度
- 10
- 标签
- 递交数
- 7457
- 已通过
- 22
- 上传者