• Bzoj 1579: [Usaco2009 Feb]Revamping Trails 道路升级 dijkstra,堆,分层图


    1579: [Usaco2009 Feb]Revamping Trails 道路升级

    Time Limit: 10 Sec  Memory Limit: 64 MB
    Submit: 1573  Solved: 428
    [Submit][Status][Discuss]

    Description

    每天,农夫John需要经过一些道路去检查牛棚N里面的牛. 农场上有M(1<=M<=50,000)条双向泥土道路,编号为1..M. 道路i连接牛棚P1_i和P2_i (1 <= P1_i <= N; 1 <= P2_i<= N). John需要T_i (1 <= T_i <= 1,000,000)时间单位用道路i从P1_i走到P2_i或者从P2_i 走到P1_i 他想更新一些路经来减少每天花在路上的时间.具体地说,他想更新K (1 <= K <= 20)条路经,将它们所须时间减为0.帮助FJ选择哪些路经需要更新使得从1到N的时间尽量少. 

    Input

    * 第一行: 三个空格分开的数: N, M, 和 K * 第2..M+1行: 第i+1行有三个空格分开的数:P1_i, P2_i, 和 T_i 

    Output

    * 第一行: 更新最多K条路经后的最短路经长度.

    Sample Input

    4 4 1
    1 2 10
    2 4 10
    1 3 1
    3 4 100

    Sample Output

    1

    HINT

    K是1; 更新道路3->4使得从3到4的时间由100减少到0. 最新最短路经是1->3->4,总用时为1单位. N<=10000

    Source

    Gold

    题解:

    分层图+dijkstra+堆优化

    直接将相邻两层相连,每层内也要连。然后从1开始跑最短路。最后把每层的最后一个的值取个最小即可。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define MAXN 10010
     4 #define MAXM 50010
     5 #define INF 1e9
     6 struct node
     7 {
     8     int end,value,next;
     9 }edge[21*4*MAXM];
    10 int cnt,Head[21*MAXN],N,dis[21*MAXN],Heap[21*MAXN],pos[21*MAXN],SIZE,U[MAXM],V[MAXM],VAL[MAXM];
    11 void addedge(int bb,int ee,int vv)
    12 {
    13     edge[++cnt].end=ee;edge[cnt].value=vv;edge[cnt].next=Head[bb];Head[bb]=cnt;
    14 }
    15 void addedge1(int bb,int ee,int vv)
    16 {
    17     addedge(bb,ee,vv);addedge(ee,bb,vv);
    18 }
    19 int read()
    20 {
    21     int s=0,fh=1;char ch=getchar();
    22     while(ch<'0'||ch>'9'){if(ch=='-')fh=-1;ch=getchar();}
    23     while(ch>='0'&&ch<='9'){s=s*10+(ch-'0');ch=getchar();}
    24     return s*fh;
    25 }
    26 void Push1(int k)
    27 {
    28     int now=k,root;
    29     while(now>1)
    30     {
    31         root=now/2;
    32         if(dis[Heap[root]]<=dis[Heap[now]])return;
    33         swap(Heap[root],Heap[now]);
    34         swap(pos[Heap[root]],pos[Heap[now]]);
    35         now=root;
    36     }
    37 }
    38 void Insert(int k)
    39 {
    40     Heap[++SIZE]=k;pos[k]=SIZE;Push1(SIZE);
    41 }
    42 void Pop1(int k)
    43 {
    44     int now,root=k;
    45     pos[Heap[k]]=0;Heap[k]=Heap[SIZE--];if(SIZE>0)pos[Heap[k]]=k;
    46     while(root<=SIZE/2)
    47     {
    48         now=root*2;
    49         if(now<SIZE&&dis[Heap[now+1]]<dis[Heap[now]])now++;
    50         if(dis[Heap[root]]<=dis[Heap[now]])return;
    51         swap(Heap[root],Heap[now]);
    52         swap(pos[Heap[root]],pos[Heap[now]]);
    53         root=now;
    54     }
    55 }
    56 void dijkstra(int start)
    57 {
    58     int i,v,u;
    59     for(i=1;i<=N;i++)dis[i]=INF;dis[start]=0;
    60     for(i=1;i<=N;i++)Insert(i);
    61     while(SIZE>0)
    62     {
    63         u=Heap[1];Pop1(pos[u]);
    64         for(i=Head[u];i!=-1;i=edge[i].next)
    65         {
    66             v=edge[i].end;
    67             if(dis[v]>dis[u]+edge[i].value){dis[v]=dis[u]+edge[i].value;Push1(pos[v]);}
    68         }
    69     }
    70 }
    71 int main()
    72 {
    73     int n,m,i,MN,j,k;
    74     n=read();m=read();k=read();
    75     for(i=1;i<=m;i++)
    76     {
    77         U[i]=read();V[i]=read();VAL[i]=read();
    78     }
    79     memset(Head,-1,sizeof(Head));cnt=1;
    80     N=(k+1)*n;
    81     for(i=0;i<=k;i++)
    82     {
    83         for(j=1;j<=m;j++)addedge1(i*n+U[j],i*n+V[j],VAL[j]);
    84         if(i!=k)
    85         {
    86             for(j=1;j<=m;j++){addedge(i*n+U[j],(i+1)*n+V[j],0);addedge(i*n+V[j],(i+1)*n+U[j],0);}
    87         }
    88     }
    89     dijkstra(1);
    90     MN=INF;
    91     for(i=0;i<=k;i++)MN=min(MN,dis[i*n+n]);
    92     printf("%d",MN);
    93     fclose(stdin);
    94     fclose(stdout);
    95     return 0;
    96 }
  • 相关阅读:
    【题解】Luogu1308 统计单词数
    【题解】Luogu1739 表达式括号匹配
    等待
    封城日记
    【题解】luoguP5717三角形分类
    【题解】LuoguP1059明明的随机数
    我是一个跳表
    【JVM故事】了解JVM的结构,好在面试时吹牛
    【JVM故事】一个Java字节码文件的诞生记
    Java多线程通关——基础知识挑战
  • 原文地址:https://www.cnblogs.com/Var123/p/5327574.html
Copyright © 2020-2023  润新知