• G


    https://lpc.ucfprogrammingteam.org/localFiles/local2019Problems.pdf(G题)

    万物皆可网络流,冲冲冲

    #include<map>
    #include<set>
    #include<cmath>
    #include<deque>
    #include<queue>
    #include<stack>
    #include<string>
    #include<bitset>
    #include<cstdio>
    #include<vector>
    #include<iomanip>
    #include<cstring>
    #include<sstream>
    #include<iostream>
    #include<algorithm>
    //#include<bits/stdc++.h>
    #define fi first
    #define se second
    #define eps 1e-2
    #define ll long long 
    #define pb push_back
    #define maxn 210050
    #define inf 0x3f3f3f3f
    #define INF 0x3f3f3f3f3f3f3f3f
    #define P pair<ll, ll>
    #define pi acos(-1)
    #define lson l,mid,rt*2
    #define rson mid+1,r,rt*2+1
    #define lowbit(x) (x&(-x))
    #define SZ(x) ((int)(x).size())
    #define met(a,x) memset(a,x,sizeof(a))
    #define openin(x) freopen(x, "r", stdin)
    #define openout(x) freopen(x, "w",stdout)
    #define rep(i,a,b) for(ll i = a;i <= b;i++)
    #define bep(i,a,b) for(ll i = a;i >= b;i--)
    #define ios() ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    using namespace std;
    const ll mod = 1000000007;
    inline int read() {
        int x = 0; char ch = getchar();
        for (; !isdigit(ch); ch = getchar());
        for (; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
        return x;
    }
    int cnt, head[maxn], vis[maxn], pre[maxn], last[maxn], flow[maxn];
    int n, m, s, t;
    ll dis[maxn], h[maxn];
    struct node {
        ll v, w, c, net;
    }e[maxn];
    void add(int u, int v, int w, int c) {
        e[cnt] = node { v, w, c, head[u] };
        head[u] = cnt++;
    }
    void add_Edge(int u, int v, int w, int c) {
        add(u, v, w, c);
        add(v, u, 0, -c);
    }
    bool spfa(int s, int t) {
        rep(i, 0, n*m) {
            vis[i] = 0; pre[i] = -1; last[i] = -1; flow[i] = inf; dis[i] = inf;
        }
        dis[s] = 0;
        queue<int>que;
        que.push(s);
        while (!que.empty()) {
            int u = que.front();
            que.pop();
            vis[u] = 0;
            for (int i = head[u]; i != -1; i = e[i].net) {
                int v = e[i].v;
                int w = e[i].w;
                int c = e[i].c;
                if (dis[v] > dis[u] + c && w > 0) {
                    dis[v] = dis[u] + c;
                    pre[v] = u;
                    last[v] = i;
                    flow[v] = min(flow[u], w);
                    if (!vis[v]) {
                        vis[v] = 1;
                        que.push(v);
                    }
                }
            }
        }
        return dis[t] != inf;
    }
    int Dijkstra(int s, int t) {
        rep(i, 0, n*m) {
            vis[i] = 0; pre[i] = -1; last[i] = -1; flow[i] = inf; dis[i] = inf;
        }
        dis[s] = 0;
        priority_queue<P, vector<P>, greater<P> >que;
        que.push(P(0, s));
        while (!que.empty()) {
            P now = que.top();
            que.pop();
            int u = now.second;
            if (vis[u])continue;
            for (int i = head[u]; i != -1; i = e[i].net) {
                int v = e[i].v;
                int w = e[i].w;
                int c = e[i].c;
                if (!vis[v] && w > 0 && dis[v] > dis[u] + c + h[u] - h[v]) {
                    dis[v] = dis[u] + c + h[u] - h[v];
                    pre[v] = u;
                    last[v] = i;
                    flow[v] = min(flow[u], w);
                    que.push(P(dis[v], v));
                }
            }
        }
        return dis[t] != inf;
    }
    char a[100][100];
    int dx[4] = { -1,1,0,0 };//上下左右
    int dy[4] = { 0,0,-1,1 };
    int main() {
        cin >> n >> m;
        rep(i, 0, n*m)head[i] = -1;
        rep(i, 1, n) {
            rep(j, 1, m) {
                cin >> a[i][j];
                int v = (i - 1)*m + j;
                if (a[i][j] == 'B')add_Edge(0, v, 1, 0);
                else if (a[i][j] == 'C')add_Edge(0, v, 1, 0);
                else if (a[i][j] == 'F') {
                    t = v;
                }
            }
        }
        rep(i, 1, n) {
            rep(j, 1, m) {
                rep(k, 0, 3) {
                    int tx = i + dx[k];
                    int ty = j + dy[k];
                    if (a[i][j] != 'x' && tx >= 1 && tx <= n && ty >= 1 && ty <= m && a[tx][ty] != 'x') {
                        int u = (i - 1)*m + j;
                        int v = (tx - 1)*m + ty;
                        add_Edge(u, v, 1, 1);
                    }
                }
            }
        }
        ll mx_flow = 0, mi_cost = 0;
        while (Dijkstra(s, t)) { //起点0,终点t <--> F
            mx_flow += flow[t];
            mi_cost += flow[t] * (dis[t] - h[s] + h[t]);
            for (int u = t; u != s; u = pre[u]) {
                ll cur = last[u];
                e[cur].w -= flow[t];
                e[cur ^ 1].w += flow[t];
            }
            rep(i, 0, n*m)h[i] += dis[i];
        }
        if (mx_flow == 2)cout << mi_cost << endl;//两人都可到达Ford
        else cout << -1 << endl;
        getchar();
        getchar();
        return 0;
    }
    View Code
  • 相关阅读:
    §6 矢量在轴上的投影(射影)
    3§5 点与直线的位置关系
    第十八章 机械振动基础
    第五章摩擦平衡问题
    矩阵论基础 3.4线性方程组的解
    第三章 平面与空间直线
    第九章点的复合运动
    §3 两平面的相关位置
    3§7 直线与平面的位置关系
    第十七章 碰撞
  • 原文地址:https://www.cnblogs.com/cherish-lin/p/12550945.html
Copyright © 2020-2023  润新知