牛客编程巅峰赛S1第6场 - 黄金&钻石&王者 C.dijkstra

链接:https://ac.nowcoder.com/acm/contest/6629/C
来源:牛客网

题目描述
牛牛和牛妹在进行一场星球模拟游戏,游戏规则如下:

游戏地图内共有n个星球,共有m条隧道连接这些星球。每条隧道都是双向的,每两个星球间不一定只有一条隧道。现在牛牛占领了这n个星球中的p个星球,牛妹占领了这n个星球中的q的星球(每个星球最多只能被一个人占领)。现在牛牛想知道他占领的p个星球中任意一个星球,到牛妹占领的q个星球中任意一个星球,这两个星球的最短距离是多少。

示例1
输入
复制
[1],[3,4],[[1,2,7],[2,3,6],[3,4,2],[1,3,11],[2,4,3]],4
输出
复制
10
说明
距离最近的牛牛星和牛妹星是1和4,他们之间的距离为10

示例2
输入
复制
[1],[2],[],2
输出
复制
-1
说明
所有的牛牛星和牛妹星都不联通,故输出-1

备注:
对于50%的数据:
2\leq n\leq 100,0\leq m\leq 200,1\leq p\leq 5,1\leq q\leq 5,p+q\leq n,1\leq wi\leq 1e42≤n≤100,0≤m≤200,1≤p≤5,1≤q≤5,p+q≤n,1≤wi≤1e4
对于100%的数据:
2\leq n\leq 1e5,0\leq m\leq 2e5,1\leq p\leq 1e5,1\leq q\leq 1e5,p+q\leq n,min(p,q)\leq 10,1\leq wi\leq 1e42≤n≤1e5,0≤m≤2e5,1≤p≤1e5,1≤q≤1e5,p+q≤n,min(p,q)≤10,1≤wi≤1e4
相关参数意义如下
niuniu 牛牛占领的p个星球的编号
niumei 牛妹占领的q个星球的编号
path m条隧道,每条隧道有三个数分别是ui,vi,wi。ui,vi分别是隧道的两边星球的编号,wi是它们之间的距离
nn int整型 星球个数n

const int maxn=1e6+5;
int tot,xx,yy;
int vis[maxn],dis[maxn],head[maxn];
class Solution {
public:
    /**
     * 
     * @param niuniu int整型vector 牛牛占领的p个星球的编号
     * @param niumei int整型vector 牛妹占领的q个星球的编号
     * @param path int整型vector<vector<>> m条隧道,每条隧道有三个数分别是ui,vi,wi。ui,vi分别是隧道的两边星球的编号,wi是它们之间的距离
     * @param nn int整型 星球个数n
     * @return int整型
     */
  
   struct node{
       int v,w;
       bool operator<(const node &a)const{
           return w>a.w;
       }
   };
    struct edge{
        int to,next,w;
        
    }e[maxn];
    void add(int x,int y,int z){
        e[++tot].to=y;
        e[tot].w=z;
        e[tot].next=head[x];
        head[x]=tot;
    }
    void dijkstra(){
        priority_queue<node>q;
        memset(dis,0x3f,sizeof(dis));
        dis[xx]=0;
        q.push(node{xx,dis[xx]});
        while(!q.empty()){
            int v=q.top().v;
            q.pop();
            if(v==yy)return ;
            if(vis[v])continue;
            vis[v]=1;
           for(int i=head[v];i;i=e[i].next){
               int u=e[i].to;
               int w=e[i].w;
               if(dis[u]>dis[v]+w){
                   dis[u]=dis[v]+w;
                   q.push(node{u,dis[u]});
               }
           }  
            
        }
    }
    int Length(vector<int>& nn, vector<int>& nm, vector<vector<int> >& path, int n) {
       for(auto &i:path){
           add(i[0],i[1],i[2]);
           add(i[1],i[0],i[2]);
       }
        xx=n+1,yy=n+2;
        for(auto &i:nn){
            add(xx,i,0);
            add(i,xx,0);
        }
        for(auto &i:nm){
            add(i,yy,0);
            add(yy,i,0);
        }
        dijkstra();
        
        if(dis[yy]==0x3f3f3f3f)return -1;
        return dis[yy];
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值