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\n",ans);
    }
    return 0;
}

 

 

posted on 2018-09-10 11:09  缄默火  阅读(214)  评论(0编辑  收藏  举报

导航