54pts 求调,玄双关
查看原帖
54pts 求调,玄双关
572228
WangSiHan_2011楼主2024/10/1 16:37

本地样例死循环拿54pts。。。。

求调,费用流

我用的是SSP(Dinic版)

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int MAXN = 50002;

struct Edge
{
    int v;
    ll c,w;
    int nxt;
};

int tot = 1;
int n,m,s,t;
int head[MAXN];
Edge edges[MAXN * 2];

void Add(int u,int v,ll c,ll w)
{
    edges[++tot] = {v,c,w,head[u]};
    head[u] = tot;
}

ll ansc,answ;
int now[MAXN];
ll disc[MAXN]; //容量
ll disw[MAXN]; //费用
bool vis[MAXN];
queue <int> que;

bool SPFA()
{
    memset(disw,0x3f,sizeof(disw));
    while(!que.empty()) que.pop();
    memset(vis,false,sizeof(vis));
    memset(disc,0,sizeof(disc));
    memset(now,0,sizeof(now));

    que.push(s);
    disw[s] = 0;
    vis[s] = true;
    now[s] = head[s];
    disc[s] = 0x3f3f3f3f3f3f3f3fll;

    while(!que.empty())
    {
        int u = que.front();
        vis[u] = false;
        que.pop();

        for(int i = head[u];i > 0;i = edges[i].nxt)
        {
            Edge &cur = edges[i];
            int v = cur.v;

            if(cur.c <= 0)
                continue;
            if(disw[v] > disw[u] + cur.w)
            {
                disw[v] = disw[u] + cur.w;
                disc[v] = min(disc[u],cur.c);
                now[v] = i;

                if(vis[v])
                    continue;
                vis[v] = true;
                que.push(v);
            }
        }
    }

    return (bool)(disw[t] >= 0x3f3f3f3f3f3f3f3fll);
}

bool viss[MAXN];
ll SSP(int u,ll sum)
{
    viss[u] = true;
    if(u == t)
        return sum;
    
    ll minc = 0,res = 0;
    for(int i = now[u];i > 0;i = edges[i].nxt)
    {
        int v = edges[i].v;
        if(viss[v] || edges[i].c <= 0 || disw[v] != disw[u] + edges[i].w)
            continue;
        
        minc = SSP(v,min(sum,edges[i].c));
        if(minc == 0)
            disc[v] = 0x3f3f3f3f3f3f3f3fll;
        
        edges[v].c -= minc;
        edges[v ^ 1].c += minc;

        res += minc;
        sum -= minc;
    }

    return res;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);

    cin >> n >> m >> s >> t;
    for(int i = 1;i <= m;i++)
    {
        int u,v; ll c,w;
        cin >> u >> v >> c >> w;
        Add(u,v,c,w);
        Add(v,u,0,-w);
    }

    while(!SPFA())
    {
        ll f = SSP(s,0x3f3f3f3f3f3f3f3fll);
        ansc += f;
        answ += f * disw[t];
    }

    cout << ansc << " " << answ << endl;
    return 0;
}
2024/10/1 16:37
加载中...