bzoj2763 [JLOI2011]飞行路线——分层图

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2763

构建分层图。

代码如下:

写法1(空间略大)(时间很慢):

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
priority_queue<pair<int,int> >q;
int const maxn=2e5+5,maxm=1500005;
int n,m,k,s,t,head[maxn],ct,dis[maxn];
bool vis[maxn];
struct N{
    int to,next,w;
    N(int t=0,int n=0,int w=0):to(t),next(n),w(w) {}
}edge[maxm<<1];
void add(int x,int y,int z)
{
    edge[++ct]=N(y,head[x],z); head[x]=ct;
    edge[++ct]=N(x,head[y],z); head[y]=ct;
    for(int i=0;i<=k-1;i++)
    {
        int u=x+i*n,v=y+(i+1)*n;
        edge[++ct]=N(v,head[u],0); head[u]=ct;
        u=y+i*n,v=x+(i+1)*n;
        edge[++ct]=N(v,head[u],0); head[u]=ct;
        u=x+(i+1)*n,v=y+(i+1)*n;
        edge[++ct]=N(v,head[u],z); head[u]=ct;
        edge[++ct]=N(u,head[v],z); head[v]=ct;
    }
}
void dijkstra()
{
    memset(dis,0x3f,sizeof dis);
    dis[s]=0; q.push(make_pair(0,s));
    while(q.size())
    {
        int x=q.top().second; q.pop();
        while(vis[x]&&q.size())x=q.top().second,q.pop();
        if(vis[x])break; vis[x]=1;
        for(int i=head[x];i;i=edge[i].next)
        {
            int u=edge[i].to;
            if(dis[u]>dis[x]+edge[i].w)
            {
                dis[u]=dis[x]+edge[i].w;
                q.push(make_pair(-dis[u],u));
            }
        }
    }
}
int main()
{
    scanf("%d%d%d%d%d",&n,&m,&k,&s,&t);
    t+=k*n;
    for(int i=1,x,y,z;i<=m;i++)
    {
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);
    }
    dijkstra();
    printf("%d",dis[t]);
    return 0;
}
View Code

 写法2(空间小)(时间飞快)(bfs)(dijkstra?):

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int const maxn=10005,maxm=50005;
struct P{
    int bh,d,f;
    P(int b=0,int d=0,int f=0):bh(b),d(d),f(f) {}
    bool operator < (const P &y) const
    {
        return d>y.d;//priority_queue 是从大到小排序 
    }
}; 
priority_queue<P>q;
int n,m,K,head[maxn],ct,s,t,dis[maxn][15];
bool vis[maxn][15];
struct N{
    int to,next,w;
    N(int t=0,int n=0,int w=0):to(t),next(n),w(w) {}
}edge[maxm<<1];
void add(int x,int y,int z){edge[++ct]=N(y,head[x],z); head[x]=ct;}
void bfs()
{
    memset(dis,0x3f,sizeof dis);
    dis[s][0]=0; q.push(P(s,0,0));
    while(q.size())
    {
        int x=q.top().bh, d=q.top().d, f=q.top().f; q.pop();
        if(vis[x][f])continue;
        vis[x][f]=1;
        if(x==t)
        {
            printf("%d",d); return;
        }
        for(int i=head[x];i;i=edge[i].next)
        {
            int u=edge[i].to;
            if(f<K&&dis[u][f+1]>d&&!vis[u][f+1])
            {
                dis[u][f+1]=d;
                q.push(P(u,d,f+1));
            }
            if(dis[u][f]>d+edge[i].w&&!vis[u][f])
            {
                dis[u][f]=d+edge[i].w;
                q.push(P(u,dis[u][f],f));
            }
        }
    }
}
int main()
{
    scanf("%d%d%d%d%d",&n,&m,&K,&s,&t);
    for(int i=1,x,y,z;i<=m;i++)
    {
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z); add(y,x,z);
    }
    bfs();
    return 0;
}

 

posted @ 2018-06-22 15:08  Zinn  阅读(135)  评论(0编辑  收藏  举报