• 链式前向星&&dij堆优化


    链式前向星

    (next)指的是上一条同起点边的位置,(to)表示这条边的终点,(val)表示边权。

    (u、v、val)分别表示起点,终点,边权。

    (head[x])存以(x)为起点的,最后加入的边的位置(edge[head[u]])

    struct node{
        int next,to,val;
    }edge[maxn];
    int head[maxn];
    int tot=0;
    head[x]=-1;//根据这个需要变换遍历链式的方法
    void add(int u,int v,int val){
        edge[++tot].to=v;
        edge[tot].val=val;
        edge[tot].next=head[u];
        head[u]=tot;
    }
    

    dij堆优化

    priority_queue<pii,vector<pii >,greater<pii > >qp;
    int dis[maxn],vis[maxn];
    void dijkstra(int src){
        for(int i=1;i<=n;++i){
            dis[i]=INF;
        }
        dis[src]=0;
       qp.push({0,src});
        while(!qp.empty()){
            pii t=qp.top;qp.pop();
            int u=t.second;
            if(vis[u])continue;
            vis[u]=1;
            for(int i=head[u];i;i=edge[i].next){
                if(dis[edge[i].to]>dis[u]+edge[i].val){
                    dis[edge[i].to]=dis[u]+edge[i].val;
                    qp.push({dis[edge[i].to],edge[i].to});
                }
            }
        }
    }
    

    链接:https://ac.nowcoder.com/acm/problem/14550
    来源:牛客网

    题目描述

    小z放假了,准备到RRR城市旅行,其中这个城市有N个旅游景点。小z时间有限,只能在三个旅行景点进行游玩。小明租了辆车,司机很善良,说咱不计路程,只要你一次性缴费足够,我就带你走遍RRR城。

    小z很开心,直接就把钱一次性缴足了。然而小z心机很重,他想选择的路程尽量长。

    然而司机也很聪明,他每次从一个点走到另外一个点的时候都走最短路径。

    你能帮帮小z吗?

    需要保证这三个旅行景点一个作为起点,一个作为中转点一个作为终点。(一共三个景点,并且需要保证这三个景点不能重复).

    输入描述:

    本题包含多组输入,第一行输入一个整数t,表示测试数据的组数
    每组测试数据第一行输入两个数N,M表示RRR城一共有的旅游景点的数量,以及RRR城中有的路的数量。
    接下来M行,每行三个数,a,b,c表示从a景点和b景点之间有一条长为c的路
    t<=40
    3<=N,M<=1000
    1<=a,b<=N
    1<=c<=100
    

    输出描述:

    每组数据输出两行,
    每组数据包含一行,输出一个数,表示整条路程的路长。
    如果找不到可行解,输出-1.
    

    思路:

    遍历中转点,找出和中转点距离最大的两个地方分别作为起点和终点。

    我选择了链式前向星+dij

    链式前向星遍历时采用

    for(int i=head[u];i;i=edge[i].next){
    }
    
    #include<bits/stdc++.h>
    #define INF 0x3f3f3f3f
    #define DOF 0x7f7f7f7f
    #define endl '
    '
    #define mem(a,b) memset(a,b,sizeof(a))
    #define debug(case,x); cout<<case<<"  : "<<x<<endl;
    #define open freopen("ii.txt","r",stdin)
    #define close freopen("oo.txt","w",stdout)
    #define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pii;
    typedef pair<long long,long long> PII;
    const int maxn = 2e5 + 10;
    int n,m;
    int dis[maxn],vis[maxn];
    priority_queue<pii,vector<pii >,greater<pii> >qp;
    struct edge{
        int next;
        int to;
        int val;
    }edge[maxn];
    int head[maxn];
    int tot=0;
    void add(int u,int v,int val){
        edge[++tot].to=v;
        edge[tot].val=val;
        edge[tot].next=head[u];
        head[u]=tot;
    }
    
    int dij(int src){
        while(!qp.empty())qp.pop();
        for(int i=1;i<=n;++i){
            dis[i]=INF;vis[i]=0;
        }
        dis[src]=0;
        qp.push({0,src});
        int x=0,y=0;
        while(!qp.empty()){
            pii t=qp.top();qp.pop();
            int u=t.second;
            if(vis[u])continue;
            vis[u]=1;
            y=max(y,dis[u]);
            if(y>x)swap(x,y);
            for(int i=head[u];i;i=edge[i].next){
                if(vis[edge[i].to])continue;
                if(dis[edge[i].to]>dis[u]+edge[i].val){
                    dis[edge[i].to]=dis[u]+edge[i].val;
                    qp.push({dis[edge[i].to],edge[i].to});
                }
            }
        }
        if(!y)return 0;
        else return x+y;
    }
    
    int main(){
        int t;cin>>t;
        while(t--){
            cin>>n>>m;
            for(int i=1;i<=n;++i)head[i]=-1;
            int a,b,c;
            while(m--){
                cin>>a>>b>>c;
                add(a,b,c);add(b,a,c);
            }
            int ans=-1;
            for(int i=1;i<=n;++i){
                ans=max(dij(i),ans);
            }
            if(ans)cout<<ans<<endl;
            else cout<<-1<<endl;
    
        }
    }
    
    
  • 相关阅读:
    Python
    Python
    Python
    #2035:人见人爱A^B
    #2030:汉字统计--统计给定文本文件中汉字的个数
    #2028:Lowest Common Multiple Plus(n个数的最小公倍数)
    幂次方的四种快速取法(不使用pow函数)
    爬楼梯:经典动态规划+递归法
    最小生成树算法【图解】:一文带你理解什么是Prim算法和Kruskal算法
    KMP算法-从头到尾彻底理解KMP
  • 原文地址:https://www.cnblogs.com/waryan/p/13329939.html
Copyright © 2020-2023  润新知