HDU6166 Senior Pan 【Dijkstra】

鏈接


老年選手,腦洞真心跟不上啊

k個點,可以分爲2個集合s1,s2
顯然dijkstra一遍即可得到s1到s2的最小距離

考慮枚舉2進制的每一位
若第i位=1,則分進s1,否則分進s2
顯然所有不同的pair組合都被包含了

#include<stdio.h>
#include<bits/stdc++.h>
#define ll long long
#define pii pair<int,int>
#define pll pair<ll,ll>
#define MEM(a,x) memset(a,x,sizeof(a))
#define lowbit(x) ((x)&-(x))

using namespace std;

const int inf=1e9+7;
const int N=100000+5;//頂點數

vector<pll>G[N];
vector<int>sel;

ll dis[N];

void Dijkstra(int n,const vector<int>&s){
    fill(dis,dis+n+1,1e18);
    priority_queue<pll,vector<pll>,greater<pll> >que;
    for(int x:s){
        dis[x]=0;
        que.push({dis[x],x});
    }
    while(!que.empty()){
        int u=que.top().second;
        que.pop();
        for(const pll&e:G[u]){
            ll v=e.first,w=e.second;
            if(dis[v]>dis[u]+w){
                dis[v]=dis[u]+w;
                que.push({dis[v],v});
            }
        }
    }
}

vector<int>s,e;
ll slove(int n){
    ll ans=1e18;
    for(int i=0;i<20;++i){
        s.clear();
        e.clear();
        for(int j:sel){
            if((j>>i)&1){
                s.push_back(j);
            }
            else{
                e.push_back(j);
            }
        }
        Dijkstra(n,s);
        for(int x:e){
            ans=min(ans,dis[x]);
        }
        Dijkstra(n,e);
        for(int x:s){
            ans=min(ans,dis[x]);
        }
    }
    return ans;
}

int main()
{
    //freopen("/home/lu/code/r.txt","r",stdin);
    //freopen("/home/lu/code/w.txt","w",stdout);
    int T;
    scanf("%d",&T);
    for(int tt=1;tt<=T;++tt){
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;++i){
            G[i].clear();
        }
        for(int i=0;i<m;++i){
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            G[u].push_back({v,w});
            //G[v].push_back({u,w});
        }
        int k;
        scanf("%d",&k);
        sel.clear();
        while(k--){
            int x;
            scanf("%d",&x);
            sel.push_back(x);
        }
        printf("Case #%d: %lld\n",tt,slove(n));
    }
    return 0;
}
發佈了292 篇原創文章 · 獲贊 82 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章