zoukankan      html  css  js  c++  java
  • 分层最短路

    分层最短路的理解

    模板

    洛谷P4568题解

    hdu3499题解

    用一张图解释

    就是把free的路线进行分层计算到这个点的距离最小是多少,假设点为pos

    mindis=min(mindis,dis[pos+i*n]);0<=i<=free n是多少个点

    洛谷P4568

    题意:

    在一个带权无向图,n个点,m条边,k个权力(使得一条边权变成0)

    再给起始位和终点位,给m条边的u,v,w的信息,求最少路费

    思路:

    m小于等于50000,k小于等于10,链式前向星的话需要2*2*(10+1)(双向*建零边和带权边(k+1层))

    因为当i==k的时候,权力是0,所以不用建第k层的零边的

    用dijkstra跑就行了

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define il inline
    #define it register int
    #define inf 0x3f3f3f3f
    #define lowbit(x) (x)&(-x)
    #define pii pair<int,int>
    #define mak(n,m) make_pair(n,m)
    #define mem(a,b) memset(a,b,sizeof(a))
    #define mod 998244353
    const int maxn=5e4*44;
    int n,m,k,tot,s,t;
    int head[maxn],dis[maxn],vis[maxn];
    struct node{int to,w,next;}edge[maxn];
    il void add(int u,int v,int w){
        edge[tot].to=v;edge[tot].w=w;
        edge[tot].next=head[u];head[u]=tot++;
    }
    il void dijkstra(){
        priority_queue<pii,vector<pii>,greater<pii> >q;
        dis[s]=0;q.push({dis[s],s});//q.push(mak(dis[s],s));
        while(!q.empty()){
            int now=q.top().second;
            q.pop();
            if(vis[now])continue;vis[now]=1;
            for(it i=head[now];~i;i=edge[i].next){
                int v=edge[i].to;
                if(!vis[v] && dis[v]>dis[now]+edge[i].w){
                    dis[v]=dis[now]+edge[i].w;
                    q.push({dis[v],v});
                }
            }
        }
    }
    int main(){
        while(~scanf("%d%d%d",&n,&m,&k)){
            scanf("%d%d",&s,&t);
            for(it i=0;i<maxn;i++){
                head[i]=-1;dis[i]=inf;vis[i]=0;
            }tot=0;
            for(it i=0;i<m;i++){
                int u,v,w;
                scanf("%d%d%d",&u,&v,&w);
                for(it i=0;i<=k;i++){
                    add(u+i*n,v+i*n,w);
                    add(v+i*n,u+i*n,w);
                    if(i!=k){
                        add(u+i*n,v+(i+1)*n,0);
                        add(v+i*n,u+(i+1)*n,0);
                    }
                }
            }
            dijkstra();int ans=inf;
            for(it i=0;i<=k;i++){
                ans=min(ans,dis[t+i*n]);
            }
            printf("%d
    ",ans);
        }
        return 0;
    }

    hdu3499

    题意:

    在一个带权无向图,n个点,m条边

    给m条边的u,v,w的信息,可以有一个权力使得一条边的路费减半

    再给起始位和终点位,求最少路费

    思路:

    分两层最短路,因为是很早之前的代码,贼青涩……

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<map>
    #include<string>
    #include<vector>
    #include<queue>
    #include<functional>
    #pragma warning(disable:4996)
    using namespace std;
    const int maxn = 200010;
    #define inf 0x3f3f3f3f3f3f3f
    #define mem(k,b) memset(k,b,sizeof(k))
    #define pi pair<int,int>
    #define mak(n,m) make_pair(n,m)
    #define ll long long
    vector<pi> g[maxn];
    ll a[maxn];
    bool vis[maxn];
    map<string, int>mp;
    int i, j, k, n, l, m, s, t, w;
    string p, q;
    struct cmp2 {
         bool operator()(const pi a,const pi b){
            return a.second > b.second;
        }
    };
    /*struct cmp2{
        friend bool operator<(const pi a, const pi b){
            return a.second > b.second;
        }
    };*/
    inline void di(int s){
        priority_queue<pi, vector<pi>, cmp2 >q;
        a[s] = 0;
        q.push(mak(s, 0));
        while (!q.empty())
        {
            pi tmp = q.top(); q.pop();
            int u = tmp.first;
            if (vis[u]){
                continue;
            }
            vis[u] = true;
            for (int i = 0; i < g[u].size(); i++)
            {
                int v = g[u][i].first;
                int w = g[u][i].second;
                if (a[v] > a[u] + w)
                {
                    a[v] = a[u] + w;
                    q.push(mak(v, a[v]));
                }
            }
        }
    }
    int main()
    {
        while (~scanf("%d%d", &n, &m)){
            int nn = n << 1;
            for (int i = 0; i <= nn; i++){
                g[i].clear();
                a[i] = inf;
                vis[i] = false;
            }
            mp.clear();
            int t1 = 1;
            for (int i = 0; i < m; i++){
                cin >> q >> p;
                scanf("%d", &t);
                if (mp[p] == 0){
                    mp[p] = t1;
                    t1++;
                }
                if (mp[q] == 0){
                    mp[q] = t1;
                    t1++;
                }
                g[mp[q]].push_back(mak(mp[p], t));
                g[mp[q]].push_back(mak(mp[p] + n, t / 2));
                g[mp[q] + n].push_back(mak(mp[p] + n, t));
            }
            cin >> q >> p;
            if (mp[p] == 0){
                mp[p] = t1++;
            }
            if (mp[q] == 0){
                mp[q] = t1++;
            }
            int kai = mp[q], jie = mp[p];
            di(kai);
            ll ans = (a[jie], a[jie + n]);
            if (ans == inf){
                printf("-1
    ");
            }
            else{
                printf("%lld
    ", ans);
            }
        }
        return 0;
    }

    模板 返回顶部

    #define ll long long
    #define il inline
    #define it register int
    #define inf 0x3f3f3f3f
    #define lowbit(x) (x)&(-x)
    #define pii pair<int,int>
    #define mak(n,m) make_pair(n,m)
    #define mem(a,b) memset(a,b,sizeof(a))
    #define mod 998244353
    
    int n,m,k,tot,s,t;
    int head[maxn],dis[maxn],vis[maxn];
    struct node{int to,w,next;}edge[maxn];
    
    il void add(int u,int v,int w){
        edge[tot].to=v;edge[tot].w=w;
        edge[tot].next=head[u];head[u]=tot++;
    }
    
    
    il void dijkstra(){
        priority_queue<pii,vector<pii>,greater<pii> >q;
        dis[s]=0;q.push({dis[s],s});//q.push(mak(dis[s],s));
        while(!q.empty()){
            int now=q.top().second;
            q.pop();
            if(vis[now])continue;vis[now]=1;
            for(it i=head[now];~i;i=edge[i].next){
                int v=edge[i].to;
                if(!vis[v] && dis[v]>dis[now]+edge[i].w){
                    dis[v]=dis[now]+edge[i].w;
                    q.push({dis[v],v});
                }
            }
        }
    }
    
    scanf("%d%d%d",&u,&v,&w);
    for(it i=0;i<=k;i++){
         add(u+i*n,v+i*n,w);
         add(v+i*n,u+i*n,w);
         if(i!=k){
               add(u+i*n,v+(i+1)*n,0);
               add(v+i*n,u+(i+1)*n,0);
          }
    }
  • 相关阅读:
    关于react fiber的理解
    前段框架——VueX
    前段框架——Vue组件间传值
    前段框架——Vue的get和post请求数据
    前段框架——Vue的一级路由和二级路由
    前端框架——Vue脚手架
    前段框架——Vue
    关于Tomcat的BUG
    验证身份证号格式
    mysql 占用90%多的CPU,解决思路
  • 原文地址:https://www.cnblogs.com/luoyugongxi/p/12442978.html
Copyright © 2011-2022 走看看