QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#642018#5114. Cells ColoringPonyHexTL 3ms10892kbC++203.9kb2024-10-15 08:55:302024-10-15 08:55:30

Judging History

你现在查看的是最新测评结果

  • [2024-10-15 08:55:30]
  • 评测
  • 测评结果:TL
  • 用时:3ms
  • 内存:10892kb
  • [2024-10-15 08:55:30]
  • 提交

answer

#define _CRT_SECURE_NO_WARNINGS 1
#include<bits/stdc++.h>
#include<unordered_map>
#include<unordered_set>
using namespace std;
#define double long double
//#define int long long
#define lc u<<1
#define rc u<<1|1
#define endl "\n"
#define X first
#define Y second
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> PII;
const ll N = 2e5 + 50;
const ll maxm = 2e18;
const ll mod = 1e9+7;

ll exgcd(ll a, ll b, ll& x, ll& y);

ll ksm(ll a, ll b) {
    ll base = a;
    ll ans = 1;
    while (b) {
        if (b & 1)ans *= base;
        ans %= mod;
        base *= base; base %= mod;
        b >>= 1;
    }
    return ans%mod;
}

char mp[300][300];
ll n, m, cc, d;
ll mf[N * 2], prv[N * 2];
ll st, ed;
struct eage {
    ll v, next, c;
}e[N];
ll h[N], idx = 1;
void add(ll u, ll v,ll c) {
    e[++idx] = { v,h[u],c }; h[u] = idx;
    e[++idx] = { u,h[v],c }; h[v] = idx;
}

bool bfs() {
    memset(mf, 0, sizeof mf);
    queue<ll>q;
    q.push(st);
    //这里初始状态没设置好
    //转移的过程中mf为最大流,mf[st]应为无限大
    mf[st] = maxm;
    while (q.size()) {
        ll u = q.front();
        q.pop();
        for (int i = h[u]; i; i = e[i].next) {
            ll v = e[i].v;
            if (e[i].c && mf[v] == 0) {
                mf[v] = min(e[i].c, mf[u]);
                prv[v] = i;
                q.push(v);
                if (v == ed)return true;
            }
        }
    }
    return false;
}

ll ek() {
    ll flow = 0;
    while (bfs()) {
        //获取了增广路径
        ll v = ed;
        while (v != st) {
            ll i = prv[v];
            ll u = e[i ^ 1].v;
            e[i].c -= mf[ed];
            e[i ^ 1].c += mf[ed];
            v = u;
        }
        flow += mf[ed];
    }
    return flow;
}

void solve()
{
    //现在尝试网络流解法,听xixu说起,其实是要对行和列建边,
    //其实有思路,但是不知道是不是正解
    cin >> n >> m >> cc >> d; idx = 0;
    st = n + m + 1; ed = n + m + 2;
    ll mx = 0, sum = 0;
    for (int i = 1; i <= n; i++) {
        ll mid = 0;
        for (int j = 1; j <= m; j++) {
            cin >> mp[i][j];
            if (mp[i][j] == '.')mid++, sum++;
        }
        mx = max(mx, mid);
    }
    for (int j = 1; j <= m; j++) {
        ll mid = 0;
        for (int i = 1; i <= n; i++) {
            if (mp[i][j] == '.')mid++;
        }
        mx = max(mx, mid);
    }
    ll ans = maxm;
    for (int c = 0; c <= mx; c++) {//枚举c建图,然后找最大流
        for (int i = 1; i <= n+m+2; i++)h[i] = 0;
        idx = 1;
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                //对每行每列建边
                if (mp[i][j] == '.') {
                    add(i, n + j, 1); add(n+j,i, 0);
                }
            }
        }
        for (int i = 1; i <= n; i++) {
            add(st, i, c); add(i, st, 0);
        }
        for (int j = 1; j <= m; j++) {
            add(n+j, ed, c); add(ed, n+j, 0);
        }
        ll val = ek(); //cout << val << endl;
        ans = min(ans, cc * c + d * (sum - val));
    }
    cout << ans << endl;
    return;
}

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    ll t = 1; //cin >> t;
    while (t--)solve();
    return 0;
}
/*PonyHex*/


ll exgcd(ll a, ll b, ll& x, ll& y) {
    if (b == 0) {
        x = 1; y = 0;
        return a;
    }
    ll g = exgcd(b, a % b, x, y);
    ll temp = x;
    x = y;
    y = temp - (a / b) * y;
    return g;
}
/*
1
11
1 2 3 2 5 6 7 6 9 1
*/
/*
ll ksm(ll a, ll b) {
    ll base = a;
    ll ans = 1;
    while (b) {
        if (b & 1)ans *= base;
        base *= base;
        b >>= 1;
    }
    return ans;
}*/
/*
ll gcd(ll a, ll b) {
    return b ? gcd(b, a % b) : a;
}*/

詳細信息

Test #1:

score: 100
Accepted
time: 3ms
memory: 10892kb

input:

3 4 2 1
.***
*..*
**..

output:

4

result:

ok 1 number(s): "4"

Test #2:

score: 0
Accepted
time: 0ms
memory: 10848kb

input:

3 4 1 2
.***
*..*
**..

output:

2

result:

ok 1 number(s): "2"

Test #3:

score: -100
Time Limit Exceeded

input:

250 250 965680874 9042302
..**.*****..**..**.*****..***..***.**......*.***.*...***.*....*.**.*.**.*.*.****...*.******.***.************....**.*..*..***.*******.*.***.*..**..****.**.*.*..***.****..**.....***.....*.****...*...*.***..****..**.*.*******..*.*******.*.*.*.****.*.***
....**.*******.*.******...

output:


result: