Ruta HDU 6705 (dos puntos + búsqueda)

Significado del título: para un gráfico ponderado dirigido, encuentre el k-ésimo camino más grande en el gráfico

Idea: A diferencia del enfoque de cola de prioridad convencional, lo que considero es que siempre que se establezca el valor máximo de una ruta, todos los valores de ruta no menores que el valor máximo se pueden obtener mediante enumeración de fuerza bruta. La complejidad de esta fuerza bruta es O (máx. (k)), por lo que al dividir en cubitos el valor máximo, puede encontrar una secuencia de ruta que cumpla con las condiciones. Esta secuencia de ruta solo debe ser mayor o igual al valor máximo de consulta max (k). Si el número de secuencias es menor que el número de consultas, el máximo Si el valor es mayor que el valor máximo, disminuya el valor máximo. Dado que puede haber algunas rutas idénticas, no hay garantía de que la cantidad de rutas menores que un cierto valor sea completamente igual a max (k), por lo que cuando juzgue que la cantidad de secuencias es demasiado, debe agregar 100 a ma.

Código:

#include <bits/stdc++.h>
#define x first
#define y second
#define mid (l+r>>1)
using namespace std;
typedef long long ll;
typedef vector<int>vi;
typedef pair<int,int> pii;
const int inf=0x3f3f3f3f;
const ll linf=0x3f3f3f3f3f3f3f3f;
const int maxn=1e5+10;
const ll mod=1e9+7;
const double PI=acos(0)*2;
int n,m,q,k[maxn],ma;
vector<pii>edg[maxn];
vector<ll> ans,tmp;
void init()
{
    for(int i=1;i<=n;i++)edg[i].clear();
    ans.clear();
    ma=0;
}
bool dfs(int u,ll now,ll goal)
{
    for(auto v:edg[u])
    {
        ll nxt=v.x+now;
        if(nxt<=goal)
        {
            if(tmp.size()==ma+100)return 0;
            tmp.push_back(nxt);
            if(dfs(v.y,nxt,goal)==0)return 0;
        }
        else break;
    }
    return 1;
}
bool can(ll v)
{
    tmp.clear();
    for(int i=1;i<=n;i++)
    {
        if(dfs(i,0,v)==0)return 1;
    }
    if(tmp.size()<ma)return 0;
    return 1;
}
void solve()
{
    cin>>n>>m>>q;
    init();
    while(m--)
    {
        int a,b,c;
        cin>>a>>b>>c;
        edg[a].push_back({c,b});
    }
    
    for(int i=0;i<q;i++)
    {
        cin>>k[i];
        ma=max(ma,k[i]);
    }
    for(int i=1;i<=n;i++)sort(edg[i].begin(),edg[i].end());

    ll l=1,r=1e15;
    while(l!=r-1)
    {
        if(can(mid))
        {
            ans.swap(tmp);
            r=mid;
        }
        else
        {
            l=mid;
        }
    }
    sort(ans.begin(),ans.end());
    for(int i=0;i<q;i++)cout<<ans[k[i]-1]<<endl;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
//    freopen("in.txt","r",stdin);
    int _;cin>>_;
    while(_--)
    {
        solve();
    }
    return 0;
}

 

Supongo que te gusta

Origin blog.csdn.net/qq_43700916/article/details/108527014
Recomendado
Clasificación