QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#555804 | #4169. 代码拍卖会 | David_Mercury | 0 | 0ms | 0kb | C++14 | 2.7kb | 2024-09-10 10:09:29 | 2024-09-10 10:09:30 |
answer
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 20, dx[4] = {0, 0, 1, -1}, dy[4] = {1, -1, 0, 0}, INF = 0x3f3f3f3f;
int n, m, s, t, e = 1, head[MAXN*MAXN*2], w[MAXN*MAXN*2], c[MAXN*MAXN*2], p[MAXN*MAXN*2];
bool inq[MAXN*MAXN*2];
char qwq[MAXN][MAXN];
inline int Trans(char c){
if(c == 'R') return 0;
if(c == 'L') return 1;
if(c == 'D') return 2;
return 3;
}
struct node{
int to, ci, wi, nxt;
} edge[MAXN*MAXN*5*2];
inline void Add_edge(int u, int v, int c, int w){
edge[++e] = (node){v, c, w, head[u]}, head[u] = e;
edge[++e] = (node){u, 0, -w, head[v]}, head[v] = e;
return;
}
inline bool EK(){
for(int i = s; i <= t; i++) w[i] = INF;
c[s] = INF, w[s] = p[t] = 0;
queue<int> que; que.push(s);
while(!que.empty()){
int x = que.front(); que.pop();
inq[x] = false;
for(int i = head[x]; i; i = edge[i].nxt){
int to = edge[i].to;
if(!edge[i].ci) continue;
if(w[to] <= w[x]+edge[i].wi) continue;
w[to] = w[x]+edge[i].wi;
c[to] = min(c[x], edge[i].ci);
p[to] = i;
if(!inq[to]) que.push(to), inq[to] = true;
}
}
return p[t];
}
inline void Update(){
for(int i = p[t]; i; i = p[edge[i^1].to])
edge[i].ci -= c[t], edge[i^1].ci += c[t];
return;
}
int main(){
cin>>n>>m;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++) cin>>qwq[i][j];
s = 0, t = n*m*2+1;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++){
Add_edge(s, (i-1)*m+j, 1, 0);
Add_edge(n*m+(i-1)*m+j, t, 1, 0);
for(int k = 0; k < 4; k++){
int x = i+dx[k], y = j+dy[k];
if(x < 1) x = n;
if(x > n) x = 1;
if(y < 1) y = m;
if(y > m) y = 1;
if(Trans(qwq[i][j]) == k) Add_edge((i-1)*m+j, n*m+(x-1)*m+y, 1, 0);
else Add_edge((i-1)*m+j, n*m+(x-1)*m+y, 1, 1);
}
}
int mincost = 0, maxflow = 0;
while(EK()) maxflow += c[t], mincost += c[t]*w[t], Update();
cout<<mincost;
return 0;
}
/*
看数据范围目测是状压 DP 之类的
但是直接状压需要压 4^n 个格子。。。
从图论的角度来说,我们要将一个内向基环树森林变为若干个环
(每个点入度至多为 4)
即每个点入度为 1 出度为 1
感觉上出奇地适配网络流,尝试
可以给每个点连四条出边,每条容量为 1,一条费用为 0 其余费用为 1,并且点拆边限制容量为 1
但是源汇很难设置
可以跑无源汇上下界可行费用最小流
怎么跑?
强制每条边的下界满流,然后检查每个点是否流量守恒
对于 out > in:说明流入不够,将其与超级汇点连边 out-in
对于 in > out:说明流出不够,将其与超级源点连边 in-out
由于图的特殊性,等价于一个点拆为出入点,然后连接成一个二分图最小带权完美匹配
*/
详细
Pretests
Final Tests
Test #1:
score: 0
Runtime Error
input:
982 473
output:
result:
Test #2:
score: 0
Time Limit Exceeded
input:
82749201374821543 5
output:
result:
Test #3:
score: 0
Time Limit Exceeded
input:
17327482917364121 7
output:
result:
Test #4:
score: 0
Time Limit Exceeded
input:
28489124728192763 1
output:
result:
Test #5:
score: 0
Time Limit Exceeded
input:
40285729174762941 25
output:
result:
Test #6:
score: 0
Time Limit Exceeded
input:
999999 499
output:
result:
Test #7:
score: 0
Time Limit Exceeded
input:
58390378572931426 113
output:
result:
Test #8:
score: 0
Time Limit Exceeded
input:
38475729495732951 491
output:
result:
Test #9:
score: 0
Time Limit Exceeded
input:
71937591037847128 487
output:
result:
Test #10:
score: 0
Time Limit Exceeded
input:
100000000000000000 491