URAL 1851|GOV-internship|最小割

一看是个巨水的最小割就来做了。

给出两个字符串由0和1组成,有些位置不知道。把第二个串去匹配第一个串,贡献代价为本次失配字符数。如何决定这些不知道的位置使总代价最小。

可以发现不知道位置只有两种状态:0和1,考虑最小割。
xi 表示’?’
那么答案就显而易见了
min{max{0,xi0}(0)+max{0,1xi}(1)+|xxj|(?,ij)}
输出方案也很简单, xi 的取值就是方案

#include <cstdio>
#include <cstring>
#include <algorithm>
#define FOR(i,j,k) for(i=j;i<=k;++i)
using namespace std;
const int N = 2555, M = 10000005, inf = 2147483647;
int h[N], p[M], v[M], w[M], edge = 1, s, t;
int level[N], cur[N], vis[N], q[N];
int a0[N], a1[N], id1[N], id2[N], loc[N];
char s1[N], s2[N];
void add(int a, int b, int c) {
    p[++edge] = h[a]; v[edge] = b; w[edge] = c; h[a] = edge;
    p[++edge] = h[b]; v[edge] = a; w[edge] = 0; h[b] = edge;
}
bool bfs() {
    int i, x, f = 0, r = 0;
    FOR(i,s,t) level[i] = -1;
    q[r++] = s; level[s] = 0;
    while (f < r) {
        x = q[f++];
        for (i = h[x]; i; i = p[i])
            if (w[i] && level[v[i]] == -1) {
                level[v[i]] = level[x] + 1;
                q[r++] = v[i];
            }
    }
    return level[t] != -1;
}
int dfs(int x, int low) {
    int i, tmp, res = 0;
    if (x == t) return low;
    for (i = cur[x]; i && res < low; i = p[i])
        if (w[i] && level[v[i]] == level[x] + 1) {
            tmp = dfs(v[i], min(low - res, w[i]));
            w[i] -= tmp; w[i ^ 1] += tmp; res += tmp;
            if (w[i]) cur[x] = i;
        }
    if (!res) level[x] = -1;
    return res;
}
int dinic() {
    int ans = 0, i;
    while (bfs()) {
        FOR(i,s,t) cur[i] = h[i];
        ans += dfs(s, inf);
    }
    return ans;
}
void dfs(int x) {
    if (vis[x]) return;
    vis[x] = 1;
    for (int i = h[x]; i; i = p[i])
        if (w[i]) dfs(v[i]);
}
int main() {
    int n, m, i, j, k, cnt = 0, ans = 0, e;
    scanf("%s%s", s1 + 1, s2 + 1);
    n = strlen(s1 + 1); m = strlen(s2 + 1);
    FOR(i,1,n) if (s1[i] == '?') id1[i] = ++cnt, loc[cnt] = i; e = cnt;
    FOR(i,1,m) if (s2[i] == '?') id2[i] = ++cnt, loc[cnt] = i;
    FOR(i,1,n) if (i + m - 1 <= n)
        for (j = 1, k = i; j <= m; ++j, ++k) {
            if (s1[k] == '0' && s2[j] == '1') ++ans;
            if (s1[k] == '1' && s2[j] == '0') ++ans;
            if (s1[k] == '?' && s2[j] == '0') ++a0[id1[k]];
            if (s1[k] == '?' && s2[j] == '1') ++a1[id1[k]];
            if (s1[k] == '0' && s2[j] == '?') ++a0[id2[j]];
            if (s1[k] == '1' && s2[j] == '?') ++a1[id2[j]];
            if (s1[k] == '?' && s2[j] == '?')
                add(id1[k], id2[j], 1), add(id2[j], id1[k], 1);
        }
    s = 0; t = cnt + 1;
    FOR(i,1,n) if (s1[i] == '?')
        add(s, id1[i], a0[id1[i]]), add(id1[i], t, a1[id1[i]]);
    FOR(i,1,m) if (s2[i] == '?')
        add(s, id2[i], a0[id2[i]]), add(id2[i], t, a1[id2[i]]);
    printf("%d\n", ans + dinic());
    dfs(s);
    FOR(i,1,e) s1[loc[i]] = vis[i] ? '0' : '1';
    FOR(i,e+1,cnt) s2[loc[i]] = vis[i] ? '0' : '1';
    printf("%s\n%s\n", s1 + 1, s2 + 1);
    return 0;
}

GOV-internship

Description

Hello Denis,

Your internship in Team.GOV is over. Unfortunately, we cannot make you a full-time offer. Don’t be upset, because you are neither the first nor the last one. It was a great pleasure to work with you. We wish you best of luck.

Regards, Vadim Kantorov, the captain of Team.GOV

A freezing November night in the year of 2010. The dormitory of Department of Mathematics and Mechanics of Ural State University. Dim monitor light. That’s how Den Mukhametianov (the 8th team member in succession) left Team.GOV.
At the beginning of September Den returned from hot summer vacations. He was calmly browsing the photos from a trip when he got an email “You are invited to an interview with Team.GOV”. A year before Den could only dream of this.
The picture emerges in the mind as if it all had been yesterday. It was a small cozy room, Vadik settled comfortably in a rocking chair. Den coughed awkwardly and shitfed his feet. Vadik looked up and smiled. “What experience have you got?”
“Half a year in Ural SU AirBug and half a year in Ural SU Quickov.”
“Hm, not bad. What’s your favorite topic?”
“String algorithms.”
“Well, then straight to the point then,” Vadik interrupted Den. “Let’s pick a problem. Do you know what is Hamming distance between two strings of equal lengths?”
“Yes, it’s the number of positions on which the characters of the strings are not equal.”
“Exactly! Let’s define the distance from a pattern p to a string s as the sum of Hamming distances from p to all substrings of s of length | p|. In the string and in the pattern some characters are erased. You need to recover the erased characters in such a way that the distance from p to s is minimal.”

Input

The first line contains the string s, the second contains the pattern p. Both strings are not empty and their lengths don’t exceed 1000. Strings are comprised of the following characters: “0”, “1” and “?”. Here, “?” stands for erased characters that you need to recover. Length of p doesn’t exceed length of s.

Output

The first line should contain the minimal distance from p to s after all erased characters are recovered. In the second and in the third line output s and p respectively where each character “?” is replaced with either “0” or “1”.

Sample Input

00?
1?

Sample Output

2
000
10

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值