HDU 6705 Path (two points + search)

Meaning of the title: For a directed weighted graph, find the k-th largest path in the graph

Idea: Different from the conventional priority queue approach, what I consider is that as long as the maximum value of a path is set, all path values ​​not less than the maximum value can be obtained through brute force enumeration. The complexity of this brute force is O(max (k)), so by dicing the maximum value, you can find a path sequence that meets the conditions. This path sequence only needs to be greater than or equal to the maximum query value max(k). If the number of sequences is less than the number of queries, the maximum If the value is greater than the maximum value, decrease the maximum value. Since there may be some identical paths, there is no guarantee that the number of paths less than a certain value is completely equal to max(k), so when judging the number of sequences is too much, you need to add 100 to ma.

Code:

#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;
}

 

Guess you like

Origin blog.csdn.net/qq_43700916/article/details/108527014
Recommended