• bzoj 2763: [JLOI2011]飞行路线


    /*
    这做法好像有个很高大上的名字叫做分层图.
    其实就是按照题目的意思重新建图 
    节点有n个变成n*k个 每个表示节点的编号和剩下能用的k值
    然后...卡spfa 需要堆优化的dij 
    */
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<queue>
    #include<vector>
    #define pa pair<int,int>
    #define mk make_pair
    #define maxn 2000010
    using namespace std;
    int n,m,k,s,t,num,head[maxn],dis[maxn],c[maxn];
    int x[maxn],y[maxn],z[maxn],ans=0xfffffff;
    priority_queue<pa,vector<pa>,greater<pa> >q;
    bool f[maxn];
    struct node
    {
        int u,v,pre,t;
    }e[maxn];
    void Add(int from,int to,int Dis)
    {
        for(int i=head[from];i;i=e[i].pre)
          if(e[i].v==to)
            {
              e[i].t=min(e[i].t,Dis);
              return;
            }
        num++;
        e[num].u=from;
        e[num].v=to;
        e[num].t=Dis;
        e[num].pre=head[from];
        head[from]=num;
    }
    void Dij(int x)
    {
        memset(dis,127/3,sizeof(dis));
        dis[x]=0;q.push(mk(0,x));
        while(!q.empty())
          {
              int d=q.top().first;
              int k=q.top().second;q.pop();
              if(f[k])continue;f[k]=1;
              for(int i=head[k];i;i=e[i].pre)
                {
                    int v=e[i].v;
                    if(dis[v]>dis[k]+e[i].t)
                      {
                          dis[v]=dis[k]+e[i].t;
                          q.push(mk(dis[v],v));
                  }
              }
          }
    }
    int main()
    {
        scanf("%d%d%d%d%d",&n,&m,&k,&s,&t);
        s++;t++;n=n+n*k;
        for(int i=1;i<=m;i++)
          scanf("%d%d%d",&x[i],&y[i],&z[i]),x[i]++,y[i]++;
        for(int i=1;i<=m;i++)
          for(int j=1;j<=k+1;j++)
            {
              Add((x[i]-1)*(k+1)+j,(y[i]-1)*(k+1)+j,z[i]);
              Add((y[i]-1)*(k+1)+j,(x[i]-1)*(k+1)+j,z[i]);
              if(j<=k)
                {
                  Add((x[i]-1)*(k+1)+j,(y[i]-1)*(k+1)+j+1,0);
                  Add((y[i]-1)*(k+1)+j,(x[i]-1)*(k+1)+j+1,0);
                }
            }
        Dij((s-1)*(k+1)+1);
        for(int j=1;j<=k+1;j++)
           ans=min(ans,dis[(t-1)*(k+1)+j]);
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    分布式版本控制系统Git的安装与使用
    利用GitLab自动同步软件仓库
    MakerDAO 代币解释:DAI, WETH, PETH, SIN, MKR(一)
    数组 Major^
    String 类 Major^
    深度优先排序(数字全排列) Major^
    喊数字小游戏 Major^
    java数据类型 Major^
    ArrayList类的使用方法 Major^
    深度优先搜索(迷宫救人最短路径) Major^
  • 原文地址:https://www.cnblogs.com/yanlifneg/p/5719579.html
Copyright © 2020-2023  润新知