Description

给定一个流网络 \(n \le 50, m \le 100, \sum m \le 10^4\)\(q (\sum q \le 10^6)\) 次询问,每次给定一个分数 \(u/v\),问所有边的容量是 \(u/v\) 时费用流的费用。

Solution

很自然想到把每次增广的费用都记下来,对于每个询问贪心处理即可

#include <bits/stdc++.h>
using namespace std;

#define int long long
const int N = 105;

namespace flow {
    const int N = 205;
    const int M = 405;
    const int inf = 1e+12;
    struct Edge {
        int p, c, w, nxt = -1;
    } e[N];
    int s, t, tans, ans, cost, ind, bus[N], qhead = 0, qtail = -1, qu[M],vis[N], dist[N];

    void graph_link(int p, int q, int c, int w) {
        e[ind].p = q;
        e[ind].c = c;
        e[ind].w = w;
        e[ind].nxt = bus[p];
        bus[p] = ind;
        ++ind;
    }
    void make(int p, int q, int c, int w) {
        graph_link(p, q, c, w);
        graph_link(q, p, 0, -w);
    }
    int dinic_spfa() {
        qhead = 0;
        qtail = -1;
        memset(vis, 0x00, sizeof vis);
        memset(dist, 0x3f, sizeof dist);
        vis[s] = 1;
        dist[s] = 0;
        qu[++qtail] = s;
        while (qtail >= qhead) {
            int p = qu[qhead++];
            vis[p] = 0;
            for (int i = bus[p]; i != -1; i = e[i].nxt)
                if (dist[e[i].p] > dist[p] + e[i].w && e[i].c > 0) {
                    dist[e[i].p] = dist[p] + e[i].w;
                    if (vis[e[i].p] == 0)
                        vis[e[i].p] = 1, qu[++qtail] = e[i].p;
                }
        }
        return dist[t] < inf;
    }
    int dinic_dfs(int p, int lim) {
        if (p == t)
            return lim;
        vis[p] = 1;
        int ret = 0;
        for (int i = bus[p]; i != -1; i = e[i].nxt) {
            int q = e[i].p;
            if (e[i].c > 0 && dist[q] == dist[p] + e[i].w && vis[q] == 0) {
                int res = dinic_dfs(q, min(lim, e[i].c));
                cost += res * e[i].w;
                e[i].c -= res;
                e[i ^ 1].c += res;
                ret += res;
                lim -= res;
                if (lim == 0)
                    break;
            }
        }
        return ret;
    }
    vector<int> solve(int _s,int _t) {
        s=_s; t=_t;
        vector <int> vec;
        int oldcost=0;
        cost=0;
        ans=0;
        while (dinic_spfa()) {
            memset(vis, 0x00, sizeof vis);
            ans += dinic_dfs(s, inf);
            vec.push_back(cost-oldcost);
            oldcost=cost;
        }
        return vec;
    }
    void init() {
        memset(bus, 0xff, sizeof bus);
        ind=0;
    }
}

int n,m,q,t1,t2,t3;

void solve()
{
    flow::init();
    for(int i=1;i<=m;i++)
    {
        scanf("%lld%lld%lld",&t1,&t2,&t3);
        flow::make(t1,t2,1,t3);
    }
    vector<int> vec = flow::solve(1,n);
    vector<int> sum = vec;
    for(int i=1;i<sum.size();i++) sum[i]+=sum[i-1];
    scanf("%lld",&q);
    for(int i=1;i<=q;i++)
    {
        int u,v; //u/v
        scanf("%lld%lld",&u,&v);
        int g;
        if(flow::ans * u < v)
        {
            puts("NaN");
            continue;
        }
        int _v=v;
        int a0=1;
        int ans=0;
        int pos=v/u;
        v-=pos*u;
        if(pos) ans+=sum[pos-1]*u;
        ans+=vec[pos]*v;
        a0*=_v;
        g=__gcd(a0,ans);
        if(g) a0/=g, ans/=g;
        printf("%lld/%lld\n",ans,a0);
    }
}

signed main()
{
    ios::sync_with_stdio(false);
    while(~scanf("%lld%lld",&n,&m))
    {
        solve();
    }
}

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2021-06-09
  • 2021-11-25
  • 2021-12-17
猜你喜欢
  • 2022-12-23
  • 2021-08-28
  • 2021-07-25
  • 2021-11-09
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案