제출 #1333459

#제출 시각아이디문제언어결과실행 시간메모리
1333459Gabriel새로운 문제 (POI11_pro)C++20
0 / 100
1096 ms9848 KiB
#include "bits/stdc++.h"
using namespace std;
struct Arista{
    int u, v, ID_opuesto;
    long long Capacidad, Flujo;
};
struct Organizar{
    int ID;
};
vector<Arista> Lista;
vector< vector<int> > Grafo;
vector<int> Punteros, Niveles, Ruta;
int Nodo_inicial;
bool operator<(const Organizar& a, const Organizar& b){
    if(Lista[a.ID].Flujo < Lista[b.ID].Flujo) return 1;
    if(Lista[a.ID].Flujo > Lista[b.ID].Flujo) return 0;
    if(Lista[a.ID].Capacidad < Lista[b.ID].Capacidad) return 1;
    if(Lista[a.ID].Capacidad > Lista[b.ID].Capacidad) return 0;
    return Lista[a.ID].v < Lista[b.ID].v;
}
set<Organizar> Lista_del_inicio;
bool BFS(int Inicio){
    //cerr<<Inicio<<"\n";
    Nodo_inicial = Inicio;
    int n = Inicio + 20, Final = Inicio + 2;
    if(Niveles.empty()){
        Niveles.assign(n, -2);
        Punteros.assign(n, 0);
    } else {
        for(int i = 0; i < n; i++){
            Niveles[i] = -2;
            Punteros[i] = 0;
        }
    }
    queue<int> Cola;
    Cola.push(Inicio);
    Niveles[Inicio] = 0;
    while(!Cola.empty()){
        int Nodo = Cola.front();
        Cola.pop();
        for(auto E: Grafo[Nodo]){
            auto Siguiente = Lista[E];
            if(Siguiente.Flujo >= Siguiente.Capacidad) continue;
            if(Niveles[Siguiente.v] < Niveles[Nodo] + 1 and Niveles[Siguiente.v] != -2) continue;
            Niveles[Siguiente.v] = Niveles[Nodo] + 1;
            Cola.push(Siguiente.v);
        }
    }
    return Niveles[Final] != -2;
}
long long DFS(int Nodo, int Final, long long Flujo){
    //cerr<<Nodo<<"\n";
    if(Nodo == Final) return Flujo;
    if(Nodo == Nodo_inicial){
        while(!Lista_del_inicio.empty()){
            auto Siguiente = Lista[Lista_del_inicio.begin()->ID];
            //cerr<<Nodo<<" "<<Siguiente.v<<" Posible.\n";
            if(Niveles[Nodo] + 1 != Niveles[Siguiente.v]){
                //cerr<<"Fallan los niveles.\n";
                Lista_del_inicio.erase(Lista_del_inicio.begin());
                continue;
            }
            //cerr<<"Niveles correctos.\n";
            if(Siguiente.Flujo >= Siguiente.Capacidad){
                //cerr<<"Falla la capacidad.\n";
                Lista_del_inicio.erase(Lista_del_inicio.begin());
                continue;
            }
            //cerr<<"Capacidad correcta.\n";
            long long Nuevo = DFS(Siguiente.v, Final, min(Flujo, Siguiente.Capacidad - Siguiente.Flujo));
            if(Nuevo == 0){
                //cerr<<"No llega.\n";
                Lista_del_inicio.erase(Lista_del_inicio.begin());
                continue;
            }
            //cerr<<Nodo<<" "<<Siguiente.v<<" Tomado.\n";
            Flujo = min(Flujo, Nuevo);
            auto Actual = *Lista_del_inicio.begin();
            Ruta.push_back(Actual.ID);
            Lista_del_inicio.erase(Actual);
            return Flujo;
        }
        return 0;
    }
    for(; Punteros[Nodo] < Grafo[Nodo].size(); Punteros[Nodo]++){
        auto Siguiente = Lista[Grafo[Nodo][Punteros[Nodo]]];
        //cerr<<Nodo<<" "<<Siguiente.v<<" Posible.\n";
        if(Niveles[Nodo] + 1 != Niveles[Siguiente.v]) continue;
        //cerr<<"Niveles correctos.\n";
        if(Siguiente.Flujo >= Siguiente.Capacidad) continue;
        //cerr<<"Capacidad correcta.\n";
        long long Nuevo = DFS(Siguiente.v, Final, min(Flujo, Siguiente.Capacidad - Siguiente.Flujo));
        if(Nuevo == 0) continue;
        //cerr<<Nodo<<" "<<Siguiente.v<<" Tomado.\n";
        Flujo = min(Flujo, Nuevo);
        Ruta.push_back(Grafo[Nodo][Punteros[Nodo]]);
        Punteros[Nodo]++;
        return Flujo;
    }
    return 0;
}
int main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    int n, m, k;
    long long r, t;
    cin>>n>>m>>r>>t>>k;
    //cerr<<t / r<<"\n\n";
    Grafo.assign(n + m + 22, {});
    int ID = 0;
    for(int i = 0; i < k; i++){
        int a, b;
        cin>>a>>b;
        a--;
        b = b - 1 + n;
        Grafo[a].push_back(ID);
        Grafo[b].push_back(ID + 1);
        Lista.push_back({a, b, ID + 1, 1, 0});
        Lista.push_back({b, a, ID, 0, 0});
        ID += 2;
    }
    vector<int> Recuperar;
    for(int i = 0; i < n; i++){
        Lista_del_inicio.insert({ID});
        Recuperar.push_back(ID);
        Grafo[n + m + 2].push_back(ID);
        Grafo[i].push_back(ID + 1);
        Lista.push_back({n + m + 2, i, ID + 1, t / r, 0});
        Lista.push_back({i, n + m + 2, ID, 0, 0});
        ID += 2;
    }
    for(int i = n; i < n + m; i++){
        Grafo[i].push_back(ID);
        Grafo[n + m + 4].push_back(ID + 1);
        Lista.push_back({i, n + m + 4, ID + 1, 1, 0});
        Lista.push_back({n + m + 4, i, ID, 0, 0});
        ID += 2;
    }
    long long Flujo_m_ximo = 0;
    while(BFS(n + m + 2)){
        /*cerr<<"Niveles.\n";
        for(int i = 0; i < n + m + 22; i++) cerr<<Niveles[i]<<" ";
        cerr<<"\nFin.\n";*/
        long long Flujo_extra;
        while(Flujo_extra = DFS(n + m + 2, n + m + 4, LLONG_MAX)){
            //cerr<<"Fin.\n"<<Flujo_extra<<"\n";
            if(Flujo_extra == 0) break;
            Flujo_m_ximo += Flujo_extra;
            for(auto E: Ruta){
                Lista[E].Flujo += Flujo_extra;
                Lista[Lista[E].ID_opuesto].Flujo -= Flujo_extra;
            }
            Lista_del_inicio.clear();
            for(auto E: Recuperar) Lista_del_inicio.insert({E});
            /*for(auto E: Lista_del_inicio) cerr<<Lista[E.ID].u<<" "<<Lista[E.ID].v<<" "<<Lista[E.ID].Flujo<<" "<<Lista[E.ID].Capacidad<<"\n";
            cerr<<"\n";*/
            Ruta.clear();
        }
        //sort(Grafo[n + m + 2].begin(), Grafo[n + m + 2].end(), o);
    }
    cout<<Flujo_m_ximo<<" ";
    long long Penalizaci_n = 0;
    for(auto E: Grafo[n + m + 2]){
        Penalizaci_n += (Lista[E].Flujo * Lista[E].Flujo + Lista[E].Flujo) / 2;
    }
    cout<<Penalizaci_n * r<<"\n";
    for(int i = 0; i < n; i++){
        long long Contador = 0;
        for(auto E: Grafo[i]){
            auto Siguiente = Lista[E];
            if(Siguiente.Flujo != 1) continue;
            cout<<i + 1<<" "<<Siguiente.v - n + 1<<" "<<Contador * r<<"\n";
            Contador++;
        }
    }
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...