• ACM-ICPC 2018 南京赛区网络预赛 L && BZOJ 2763 分层最短路


    https://nanti.jisuanke.com/t/31001

    题意 可以把k条边的权值变为0,求s到t的最短路

    解析  分层最短路  我们建立k+1层图 层与层之间边权为0,i 向 i+1层转移,代表用了一条免费边。

    #include <bits/stdc++.h>
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define all(a) (a).begin(), (a).end()
    #define fillchar(a, x) memset(a, x, sizeof(a))
    #define huan printf("
    ");
    #define debug(a,b) cout<<a<<" "<<b<<" ";
    using namespace std;
    const int maxn=3e6+10,inf=0x3f3f3f3f;
    typedef long long ll;
    typedef pair<int,int> pii;
    int n,m,k,st,ed,cnt,head[maxn],vis[maxn];
    ll dis[maxn];
    struct node
    {
        ll from,to,val,next;
    } edge[maxn<<1];
    struct element
    {
        ll val,now;
    };
    bool operator < (element a,element b)
    {
        if(a.val==b.val)
            return a.now<b.now;
        return a.val>b.val;
    }
    void dijikstra(int s,int e)
    {
        priority_queue<element>q;
        memset(dis,0x3f,sizeof(dis));
        dis[s]=0;
        q.push(element{0,s});
        while(!q.empty())
        {
            element u=q.top();
            q.pop();
            if(vis[u.now])
                continue;
            vis[u.now]=1;
            for(int i=head[u.now]; i!=-1; i=edge[i].next)
            {
                int to=edge[i].to;
                if(dis[u.now]+edge[i].val<dis[to])
                {
                    dis[to]=dis[u.now]+edge[i].val;
                    q.push(element{dis[to],to});
                }
            }
        }
        ll ans=1e18;
        for(int i=0; i<=k; i++)
        {
            if(ans>dis[e+i*n])
                ans=dis[e+i*n];
        }
        printf("%lld
    ",ans);
    }
    void init()
    {
        memset(head,-1,sizeof(head));
        memset(vis,0,sizeof(vis));
        cnt=1;
    }
    void edgeadd(ll from,ll to,ll val)
    {
        edge[cnt].from=from;
        edge[cnt].to=to;
        edge[cnt].val=val;
        edge[cnt].next=head[from];
        head[from]=cnt++;
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            init();
            scanf("%d%d%d",&n,&m,&k);
            st=1,ed=n;
            for(int i=1; i<=m; i++)
            {
                ll x,y,z;
                scanf("%lld%lld%lld",&x,&y,&z);
                for(int i=0; i<=k; i++)   //分为k+1层图,
                {
                    edgeadd(x+i*n,y+i*n,z);  //每层图之间建边
                    if(i!=k)
                    {
                        edgeadd(x+i*n,y+(i+1)*n,0);//第层i向i+1层图建边 边权为0;
                    }
                }
            }
            dijikstra(st,ed);
        }
    }

    BZOJ 2763

    dp思想

    /**************************************************************
        Problem: 2763
        User: 1071532391
        Language: C++
        Result: Accepted
        Time:7452 ms
        Memory:6972 kb
    ****************************************************************/
     
    #include <bits/stdc++.h>
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define all(a) (a).begin(), (a).end()
    #define fillchar(a, x) memset(a, x, sizeof(a))
    #define huan printf("
    ");
    #define debug(a,b) cout<<a<<" "<<b<<" ";
    using namespace std;
    const int maxn=2e4+10,inf=0x3f3f3f3f;
    typedef long long ll;
    typedef pair<int,int> pii;
    struct edge
    {
        int u,v,w,next;
    }e[maxn*10];
    struct node
    {
        int x,y;
    };
    int cnt,dis[maxn][15],head[maxn],vis[maxn][15];
    int n,m,k,s,t;
    void init()
    {
        cnt=0;
        fillchar(head,-1);
        fillchar(vis,0);
    }
    void addedge(int u,int v,int w)
    {
        e[++cnt].next=head[u];
        e[cnt].u=u;
        e[cnt].v=v;
        e[cnt].w=w;
        head[u]=cnt;
    }
    void spfa()
    {
        fillchar(dis,0x3f);
        queue<node> q;
        q.push(node{s,k});
        dis[s][k]=0;
        while(!q.empty())
        {
            int u=q.front().x;
            int t=q.front().y;
            q.pop();
            vis[u][t]=0;
            for(int i=head[u];i!=-1;i=e[i].next)
            {
                int v=e[i].v,w=e[i].w;
                if(dis[v][t]>dis[u][t]+w)
                {
                    dis[v][t]=dis[u][t]+w;
                    if(!vis[v][t])
                    {
                        vis[v][t]=1;
                        q.push(node{v,t});
                    }
                }
                if(t>0&&dis[v][t-1]>dis[u][t])
                {
                    dis[v][t-1]=dis[u][t];
                    if(!vis[v][t-1])
                    {
                        vis[v][t-1]=1;
                        q.push(node{v,t-1});
                    }
                }
            }
        }
        int ans=1e9;
        for(int i=0;i<=k;i++)
        {
            //cout<<dis[i][0]<<" "<<i<<endl;
            ans=min(ans,dis[t][i]);
        }
        printf("%d
    ",ans);
    }
    int main()
    {
        init();
        scanf("%d%d%d%d%d",&n,&m,&k,&s,&t);
        for(int i=0;i<m;i++)
        {
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            addedge(u,v,w);
            addedge(v,u,w);
        }
        spfa();
        return 0;
    }
  • 相关阅读:
    ASP.Net无法连接Oracle的一个案例
    给Oracle添加split和splitstr函数
    笨猪大改造
    设计模式(一)策略模式
    jQuery select 操作全集
    现在的心情
    jquery 自动实现autocomplete+ajax
    c# 配置连接 mysql
    jquery.ajax和Ajax 获取数据
    C# 加密可逆
  • 原文地址:https://www.cnblogs.com/stranger-/p/9615283.html
Copyright © 2020-2023  润新知