ACM-ICPC 2018 南京赛区网络预赛 L题(分层图,堆优化)

题目链接:

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

超时代码:

#include<bits/stdc++.h>
using namespace std;
# define maxn 10000000+10
# define inf 0x3f3f3f3f
int n,m,k;
int num;
int head[maxn];
int dis[maxn];
int vis[maxn];
struct node
{
    int ne;
    int to;
    int co;
} q[maxn];
void add(int u,int v,int w)
{
    q[++num].ne=head[u];
    q[num].to=v;
    q[num].co=w;
    head[u]=num;
}
void spfa()
{
    queue<int >p;
    while(!p.empty())p.pop();
    memset(dis,inf,sizeof(dis));
    memset(vis,0,sizeof(vis));
    dis[1]=0;
    vis[1]=1;
    p.push(1);
    while(!p.empty())
    {
        int top=p.front();
        vis[top]=0;
        p.pop();
        for(int i=head[top]; i!=-1; i=q[i].ne)
        {
            int temp=q[i].to;
            if(dis[temp]>dis[top]+q[i].co)
            {
                dis[temp]=dis[top]+q[i].co;
                if(!vis[temp])
                {
                    vis[temp]=1;
                    p.push(temp);
                }
            }
        }
    }
}
void solve()
{
    spfa();
    int minn=inf;
    for(int i=0; i<=k; i++)
    {
        minn=min(minn,dis[n+i*n]);
    }
    printf("%d
",minn);
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        memset(head,-1,sizeof(head));
        num=0;
        scanf("%d%d%d",&n,&m,&k);
        if(k==0)
        {
            for(int i=1; i<=m; i++)
            {
                int u,v,w;
                scanf("%d%d%d",&u,&v,&w);
                add(u,v,w);
                add(v,u,w);
            }
            spfa();
            printf("%d
",dis[n]);
            return 0;
        }
        else
        {
            for(int i=1; i<=m; i++)
            {
                int u,v,w;
                scanf("%d%d%d",&u,&v,&w);
                for(int j=0; j<=k; j++)
                {
                    add(u+(n*j),v+(n*j),w);
                    add(v+(n*j),u+(n*j),w);
                    if(j<k)
                    {
                        add(u+(j)*n,v+(j+1)*n,0);
                        add(v+(j)*n,u+(j+1)*n,0);
                    }
                }
            }
            solve();
        }
    }
    return 0;
}

AC代码:

#include<bits/stdc++.h>
using namespace std;
# define maxn 100500
# define maxm 6000500//这个地方要注意,并不熟一层图中包括多少点就有多少条边的,还有很多边是没用的
# define inf 0x3f3f3f3f
# define ll long long
ll n,m,k;
ll num;
struct Edge
{
    ll to;
    ll ne;
    ll co;
} q[maxm];
ll head[maxm];
ll dis[maxm];
void add(ll a,ll b,ll c)
{
    q[++num].ne=head[a];
    q[num].to=b;
    q[num].co=c;
    head[a]=num;
}
struct node
{
    ll num;
    ll dis;
    node() {}
    node(ll x,ll y)
    {
        num=x;
        dis=y;
    }
    friend bool operator < (node a,node b)
    {
        return a.dis>b.dis;
    }
};
void dijkstra()
{
    priority_queue<node >p;
    memset(dis,inf,sizeof(dis));
    dis[1]=0;
    p.push(node(1,dis[1]));
    while(!p.empty())
    {
        node t=p.top();
        p.pop();
        for(int i=head[t.num]; i!=-1; i=q[i].ne)
        {
            int temp=q[i].to;
            if(dis[temp]>dis[t.num]+q[i].co)
            {
                dis[temp]=dis[t.num]+q[i].co;
                p.push(node(temp,dis[temp]));
            }
        }
    }
}
int  main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        memset(head,-1,sizeof(head));
        num=0;
        scanf("%lld%lld%lld",&n,&m,&k);
        if(k>=m)
        {
            printf("%d
",0);
            continue;
        }
        for(int i=1; i<=m; i++)
        {
            ll u,v,w;
            scanf("%lld%lld%lld",&u,&v,&w);
            for(int j=0; j<=k; j++)
            {
                add(u+n*j,v+n*j,w);
                if(j!=k)
                {
                    add(u+n*j,v+n*(j+1),0);
                }
            }
        }
        dijkstra();
        ll ans=inf ;
        for(int i=0; i<=k; i++){
        ans=min(ans,dis[n+i*n]);
     //  cout<<dis[n+i*n]<<endl;
        }
        printf("%lld
",ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/letlifestop/p/10262933.html