zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    软件测试(理论基础)
    Android NDK常见配置问题的解决方案
    Eclemma各种安装方式以及安装失败解决
    检测Buffer Overflow的几种方法
    转: 跟我一起写 Makefile
    流敏感、路径敏感、上下文敏感
    Symbolic Exectuion with Mixed ConcreteSymbolic Solving
    基于ajc的代码编织
    第一次个人编程作业
    第一次博客作业
  • 原文地址:https://www.cnblogs.com/Zinn/p/9212763.html
Copyright © 2011-2022 走看看