zoukankan      html  css  js  c++  java
  • 2018 ICPC南京网络赛 L Magical Girl Haze 题解

    大致题意:
        给定一个n个点m条边的图,在可以把路径上至多k条边的权值变为0的情况下,求S到T的最短路。

    数据规模: N100000,M200000,K10

    建一个立体的图,有k层,每一层是一份原图,消耗一次把一条边权值变为0的机会 = 在立体图中升一层

    然后跑堆优化dij就好了,会卡spfa。

    AC代码:

    #include<cstdio>
    #include<queue>
    #include<cstring>
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int MAXN=101000;
    const int MAXM=201000;
    typedef pair<long long,pair<int,int> > pii;
    priority_queue<pii,vector<pii>,greater<pii> > q;
    bool visit[MAXN][15];
    int pointer[MAXN];
    long long d[MAXN][15];
    int n,m,k,tot=0,S,T;
    const long long INF=1e17;
    struct Edge
    {
        int to,next;
        long long w;
        Edge() {};
        Edge(int b,int nxt,int weight) {to=b,next=nxt,w=weight;}
    }edge[MAXM];
    inline void addedge(int a,int b,int w1)
    {
        edge[tot]=Edge(b,pointer[a],w1);
        pointer[a]=tot++;
    }
    void dijkstra()
    {
        rep(i,S,T) rep(z,0,k) d[i][z]=INF;
        d[S][0]=0;
        memset(visit,0,sizeof(visit));
        q.push(make_pair(d[S][0],make_pair(S,0)));
        while(!q.empty())
        {
            pii u=q.top();q.pop();
            int x=u.second.first,stp=u.second.second;
            if(visit[x][stp]) continue;
            visit[x][stp]=1;
            for(int j=pointer[x];j!=-1;j=edge[j].next)
            {
                int &v=edge[j].to;
                if(d[v][stp]>d[x][stp]+edge[j].w)
                {
                    d[v][stp]=d[x][stp]+edge[j].w;
                    q.push(make_pair(d[v][stp],make_pair(v,stp)));
                }
                if(stp<k&&d[v][stp+1]>d[x][stp])
                {
                    d[v][stp+1]=d[x][stp];
                    q.push(make_pair(d[v][stp+1],make_pair(v,stp+1)));
                }
            }
        }
    }
    void init()
    {
        tot=0;
        memset(pointer,-1,sizeof(pointer));
    }
    void Input()
    {
        scanf("%d%d%d",&n,&m,&k);
        int u,v;
        long long w;
        rep(i,1,m)
        {
            scanf("%d%d%lld",&u,&v,&w);
            addedge(u,v,w);
        }
        S=1;T=n;
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        int TT;
        scanf("%d",&TT);
        rep(tt,1,TT)
        {
            init();
            Input();
            dijkstra();
            long long ans=INF;
            rep(i,0,k) ans=min(ans,d[n][i]);
            printf("%lld
    ",ans);
        }
        return 0;
    }

     

  • 相关阅读:
    c++字符串
    iOS调用相册
    cocos2d-x中有一个JniHelper类详细使用
    iOS 字符串应用
    c++调用java
    iOS调用相册、相机、上传等问题
    win32中GBK、UTF8的互转
    SQL Server海量数据查询代码优化建议
    JSON中的[]和{}
    数据库范式
  • 原文地址:https://www.cnblogs.com/zhixingr/p/9617985.html
Copyright © 2011-2022 走看看