• [BZOJ2763][JLOI2011]飞行路线


    题目描述 Description

    Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司。该航空公司一共在n个城市设有业务,设这些城市分别标记为0到n-1,一共有m种航线,每种航线连接两个城市,并且航线有一定的价格。Alice和Bob现在要从一个城市沿着航线到达另一个城市,途中可以进行转机。航空公司对他们这次旅行也推出优惠,他们可以免费在最多k种航线上搭乘飞机。那么Alice和Bob这次出行最少花费多少?

    输入描述 Input Description
    数据的第一行有三个整数,n,m,k,分别表示城市数,航线数和免费乘坐次数。
    第二行有两个整数,s,t,分别表示他们出行的起点城市编号和终点城市编号。(0<=s,t<n)
    接下来有m行,每行三个整数,a,b,c,表示存在一种航线,能从城市a到达城市b,或从城市b到达城市a,价格为c。(0<=a,b<n,a与b不相等,0<=c<=1000)
    输出描述 Output Description
      只有一行,包含一个整数,为最少花费。
    样例输入 Sample Input
    5 6 1
    0 4
    0 1 5
    1 2 5
    2 3 5
    3 4 5
    2 3 3
    0 2 100
    样例输出 Sample Output
    8
    数据范围及提示 Data Size & Hint
     对于30%的数据,2<=n<=50,1<=m<=300,k=0;

    对于50%的数据,2<=n<=600,1<=m<=6000,0<=k<=1;

    对于100%的数据,2<=n<=10000,1<=m<=50000,0<=k<=10.

     好久没有写博客了,今天多来几发:
    本题特殊条件是有k次免费,然后我就想到了状态之间的一些转移,类似f(i,j)表示当前到了第i个点,用了j次免费条边的最小花费,转移比较显然,f(i,j)可以转移到f(a,j+1)和f(a,j)。(其中a是i能到达的一些点)然而转移比较复杂,所以就可以把一个状态f(i,j)看成一个点,转移连成一些边,最后从f(s,0)到f(t,k)求一下最短路就好了。

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstdio>
     4 #include<queue>
     5 #include<cmath>
     6 #include<cstring>
     7 using namespace std;
     8 typedef long long LL;
     9 typedef pair<int,int> PII;
    10 #define mp(a,b) make_pair(a,b) 
    11 #define mem(a,b) memset(a,b,sizeof(a))
    12 inline int read()
    13 {
    14     int x=0,f=1;char c=getchar();
    15     while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
    16     while(isdigit(c)){x=x*10+c-'0';c=getchar();}
    17     return x*f;
    18 }
    19 const int maxn=110010,maxm=2000010,oo=2147483647;
    20 struct Edge
    21 {
    22     int u,v,w,next;
    23     Edge() {}
    24     Edge(int _1,int _2,int _3,int _4):u(_1),v(_2),w(_3),next(_4) {}
    25 }e[maxm<<1];
    26 int n,m,k,s,t,a,b,c,first[maxn],ce=-1,dis[maxn]; 
    27 bool vis[maxn];
    28 int id(int a,int b){return b*n+a;}
    29 void addEdge(int a,int b,int c){e[++ce]=Edge(a,b,c,first[a]);first[a]=ce;} 
    30 int Dijkstra()
    31 {
    32     priority_queue <PII,vector<PII>,greater<PII> > Q;
    33     for(int i=0;i<(k+1)*n;i++)dis[i]=oo;
    34     Q.push(make_pair(0,id(s,0)));dis[id(s,0)]=0;
    35     while(Q.size())
    36     {
    37         int now=Q.top().second;Q.pop();
    38         if(vis[now])continue;
    39         vis[now]=1;
    40         for(int i=first[now];i!=-1;i=e[i].next)
    41             if(dis[e[i].v]>dis[now]+e[i].w)
    42             {
    43                 dis[e[i].v]=dis[now]+e[i].w; 
    44                 Q.push(make_pair(dis[e[i].v],e[i].v));
    45             }
    46     }
    47     return dis[id(t,k)];
    48 }
    49 int main()
    50 {
    51     mem(first,-1);
    52     n=read();m=read();k=read();s=read();t=read();
    53     for(int i=0;i<m;i++)
    54     {
    55         a=read(),b=read(),c=read();
    56         for(int j=0;j<=k;j++)
    57         {
    58             addEdge(id(a,j),id(b,j),c);addEdge(id(b,j),id(a,j),c);
    59             if(j<k)addEdge(id(a,j),id(b,j+1),0),addEdge(id(b,j),id(a,j+1),0);
    60         }
    61     }
    62     printf("%d",Dijkstra());
    63     return 0;
    64 }
    View Code
  • 相关阅读:
    AWR报告中Top 10 Foreground Events存在”reliable message”等待事件的处理办法
    【Linux资源管理】iotop命令监控磁盘使用情况
    [Oracle]记一次由sequence引发的enq sv-contention等待事件
    Oracle session相关数据字典(一)
    Oracle在线重定义(online redefinition)--将普通表改为分区表
    oracle使用DBMS_RANDOM包生成随机数据
    Oracle split分区表引起ORA-01502错误
    Oracle查找lobsegment、lobindex对应的表
    【Zabbix】zabora批量部署
    【Zabbix】zabora监控Oracle数据库
  • 原文地址:https://www.cnblogs.com/FYH-SSGSS/p/6866398.html
Copyright © 2020-2023  润新知