QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#208352 | #5161. Last Guess | Aeren# | RE | 0ms | 3920kb | C++20 | 3.6kb | 2023-10-09 14:43:44 | 2023-10-09 14:43:45 |
Judging History
answer
#include<bits/stdc++.h>
using namespace std;
// 사용법
// Dinic dinic(n, src, snk) : 정점 n개 (0-based)인 플로우 그래프를 만든다.
// 이 때, 소스는 src, 싱크는 snk로 설정할것이다.
// dinic.AddEdge(a, b, c) : a -> b 방향으로 용량 c인 간선을 생성한다.
// dinic.AddLR(a, b, l, r) : a -> b 방향으로 유량에 [l,r] 제약이 달린 간선을 생성한다.
// dinic.check_circulation() : LR제약을 모두 만족하는 flow가 존재한다면 true를 리턴한다.
struct Dinic {
struct Edge { int next, rev, c, f; };
int N, src, snk, SRC, SNK;
int need;
vector<vector<Edge> > g;
vector<int> dist, p, pp;
void AddEdge(int a, int b, int c) {
g[a].push_back({b, g[b].size(), c, 0});
g[b].push_back({a, g[a].size()-1, 0, 0});
}
Dinic() { }
Dinic(int n, int s, int t) {
N = n;
src = s; snk = t;
SRC = N; SNK = N+1; N += 2;
need = 0;
g.resize(N);
AddEdge(snk, src, 1234567890);
}
void AddLR(int a, int b, int l, int r) { // [l, r]
assert(l <= r);
AddEdge(a, b, r-l);
AddEdge(a, SNK, l);
AddEdge(SRC, b, l);
need += l;
}
int Run(int src, int snk) {
int ret = 0;
while(1)
{
dist = p = pp = vector<int>(N, -1);
queue<int> q;
q.push(src), dist[src] = 0;
while(!q.empty())
{
int n = q.front(); q.pop();
for(int i=0; i<g[n].size(); i++)
{
auto &it = g[n][i];
if (dist[it.next] == -1 && it.c - it.f > 0)
{
q.push(it.next);
dist[it.next] = dist[n] + 1;
p[it.next] = n;
pp[it.next] = i;
}
}
}
if (dist[snk] == -1) break;
int flow = 1234567890;
for(int i=snk; i!=src; i=p[i])
flow = min(flow, g[p[i]][pp[i]].c - g[p[i]][pp[i]].f);
for(int i=snk; i!=src; i=p[i])
{
g[p[i]][pp[i]].f += flow;
g[i][g[p[i]][pp[i]].rev].f -= flow;
}
ret += flow;
}
return ret;
}
bool check_circulation()
{
int flow = Run(SRC, SNK);
Run(src, snk);
if (flow == need) return true;
else return false;
}
};
int n, m, L[256], R[256], FL[256], FR[256], ans[555];
bool chk[256][256];
string s[555], t[555];
int main()
{
ios::sync_with_stdio(0); cin.tie(0);
cin >> m >> n; m--;
for(int i=1;i<=m;i++) cin >> s[i] >> t[i];
for(int i='a';i<='z';i++) FL[i] = 0, FR[i] = n;
for(int i=1;i<=m;i++) {
memset(L, 0, sizeof L);
memset(R, -1, sizeof R);
for(int j=0;j<n;j++) {
if(t[i][j] == 'G') {
ans[j] = s[i][j];
L[s[i][j]]++;
}
}
for(int j=0;j<n;j++) {
if(t[i][j] == 'Y') {
L[s[i][j]]++;
chk[j][s[i][j]] = 1;
}
if(t[i][j] == 'B') {
R[s[i][j]] = L[s[i][j]];
chk[j][s[i][j]] = 1;
}
}
for(int i='a';i<='z';i++) {
FL[i] = max(FL[i], L[i]);
if(R[i] != -1) FR[i] = min(FR[i], R[i]);
}
}
for(int i=0;i<n;i++) if(ans[i]) {
FL[ans[i]]--, FR[ans[i]]--;
}
int src = 0, snk = n + 26 + 1;
Dinic dinic(n + 28, src, snk);
vector<vector<int> > p(n + 1, vector<int>(26, -1));
for(int i=0;i<n;i++) if(!ans[i]) {
dinic.AddLR(src, i+1, 1, 1);
for(int j='a';j<='z';j++) if(!chk[i][j]) {
p[i+1][j-'a'] = dinic.g[i+1].size();
dinic.AddEdge(i+1, n+j-'a'+1, 1);
}
}
for(int i='a';i<='z';i++) {
dinic.AddLR(n+i-'a'+1, snk, FL[i], FR[i]);
}
bool tmp = dinic.check_circulation();
assert(tmp == true);
vector<pair<int, int> > e;
for(int i=1; i<=n; i++)
for(int j=0; j<26; j++)
if (p[i][j] != -1 && dinic.g[i][p[i][j]].f == 1)
e.push_back({i, j});
for(auto [a,b] : e)
ans[a-1] = (char)(b+'a');
for(int i=0;i<n;i++) cout << char(ans[i]);
cout << endl;
}
詳細信息
Test #1:
score: 100
Accepted
time: 0ms
memory: 3872kb
input:
4 5 reply YYGBB refer BBBGG puppy YYGBB
output:
upper
result:
ok
Test #2:
score: 0
Accepted
time: 0ms
memory: 3920kb
input:
2 12 aabbccddeeff GGGYGBYYYBBB
output:
aabdcbeadaaa
result:
ok
Test #3:
score: -100
Runtime Error
input:
25 500 qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqoqqqqqqqqqqqqqqqqqqqqqqoqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqjq...