zoukankan      html  css  js  c++  java
  • 洛谷P4822 冻结

    题目描述

    “我要成为魔法少女!”
    “那么,以灵魂为代价,你希望得到什么?”
    “我要将有关魔法和奇迹的一切,封印于卡片之中„„”

    在这个愿望被实现以后的世界里,人们享受着魔法卡片((SpellCard),又名符卡)带来的便捷。

    现在,不需要立下契约也可以使用魔法了!你还不来试一试?
    比如,我们在魔法百科全书((Encyclopedia of Spells))里用“(freeze)”作为关键字来查询,会有很多有趣的结果。
    例如,我们熟知的(Cirno),她的冰冻魔法当然会有对应的 (SpellCard) 了。 当然,更加令人惊讶的是,居然有冻结时间的魔法,(Cirno) 的冻青蛙比起这些来真是小巫见大巫了。
    这说明之前的世界中有很多魔法少女曾许下控制时间的愿望,比如 (Akemi Homura)(Sakuya Izayoi)、„„
    当然,在本题中我们并不是要来研究历史的,而是研究魔法的应用。

    我们考虑最简单的旅行问题吧: 现在这个大陆上有 (N) 个城市,(M) 条双向的道路。城市编号为 (1~N),我们在 (1) 号城市,需要到 (N) 号城市,怎样才能最快地到达呢?
    这不就是最短路问题吗?我们都知道可以用 (Dijkstra、Bellman-Ford、Floyd-Warshall)等算法来解决。
    现在,我们一共有 K 张可以使时间变慢 (50\%)(SpellCard),也就是说,在通过某条路径时,我们可以选择使用一张卡片,这样,我们通过这一条道路的时间 就可以减少到原先的一半。需要注意的是:

    1. 在一条道路上最多只能使用一张 (SpellCard)

    2. 使用一张(SpellCard) 只在一条道路上起作用。

    3. 你不必使用完所有的 (SpellCard)

      给定以上的信息,你的任务是:求出在可以使用这不超过 (K) 张时间减速的 (SpellCard) 之情形下,从城市(1) 到城市(N)最少需要多长时间。

    输入输出格式

    输入格式:

    第一行包含三个整数:(N、M、K)
    接下来 (M) 行,每行包含三个整数:(A_i、B_i、Time_i),表示存在一条 (A_i)(B_i)之间的双向道路,在不使用 (SpellCard) 之前提下,通过它需要 (Time_i)的时间。

    输出格式:

    输出一个整数,表示从(1) 号城市到 (N)号城市的最小用时。

    输入输出样例

    输入样例#1:

    4 4 1 
    1 2 4 
    4 2 6 
    1 3 8 
    3 4 8 
    

    输出样例#1:

    7
    

    说明

    样例解释:
    在不使用 (SpellCard) 时,最短路为 (1à2à4),总时间为 (10)。现在我们可以使用 (1)(SpellCard),那么我们将通过 (2à4) 这条道路的时间减半,此时总时间为(7)
    对于(100\%)的数据:(1 ≤ K ≤ N ≤ 50,M ≤ 1000)
    (1≤ A_i,B_i ≤ N,2 ≤ Time_i ≤ 2000)
    为保证答案为整数,保证所有的 (Time_i)均为偶数。
    所有数据中的无向图保证无自环、重边,且是连通的。

    思路:还是跟其他的分层最短路题目一样,只不过之前的(k)次免费的机会变成了(k)次免费缩小到一半的机会,那么分层的时候我们把边权由(0)改为(w/2)就可以了。

    代码:

    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    #include<cctype>
    #define maxn 5000001
    using namespace std;
    int n,m,k,head[maxn],num,dis[maxn],s,t;
    inline int qread() {
      char c=getchar();int num=0,f=1;
      for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
      for(;isdigit(c);c=getchar()) num=num*10+c-'0';return num*f;
    }
    struct Edge {
      int v,w,nxt;
    }e[maxn];
    struct node {
      int x,y;
      bool operator < (const node &a) const {return y>a.y;}
    };
    inline void ct(int u, int v, int w) {
      e[++num].v=v;
      e[num].w=w;
      e[num].nxt=head[u];
      head[u]=num;
    }
    priority_queue<node>q;
    inline void dijkstra() {
      memset(dis,0x3f,sizeof(dis));
      dis[1+n*k]=0;q.push((node){1+n*k,0});
      while(!q.empty()) {
      	int u=q.top().x,d=q.top().y;
      	q.pop();
      	if(d!=dis[u]) continue;
      	for(int i=head[u];i;i=e[i].nxt) {
      	  int v=e[i].v;
    	  if(dis[v]>dis[u]+e[i].w) {
    	  	dis[v]=dis[u]+e[i].w;
    	  	q.push((node){v,dis[v]});
    	  }	
    	}
      }
    }
    int main() {
      n=qread(),m=qread(),k=qread();
      for(int i=1,u,v,w;i<=m;++i) {
      	u=qread(),v=qread(),w=qread();
      	for(int j=0;j<=k;++j) {
      	  ct(u+j*n,v+j*n,w);
    	  ct(v+j*n,u+j*n,w);
    	  if(j) {
    	  	ct(u+j*n,v+(j-1)*n,w/2);
    	  	ct(v+j*n,u+(j-1)*n,w/2);
    	  }	
    	}
      }
      dijkstra();
      int zrj=0x7fffffff;
      for(int i=0;i<=k;++i) zrj=min(zrj,dis[n+i*n]);
      printf("%d
    ",zrj);
      return 0; 
    }
    
    孤注一掷,我怎甘落空?!
  • 相关阅读:
    基于Delphi的三层数据库系统的实现方法
    用数据表创建树_delphi教程
    多层数据库开发十三:剖析几个数据库应用程序
    多层数据库开发十二:使用数据控件
    多层数据库开发九:查询数据库
    第十一章 TClientDataSet
    用python做线性规划
    Python-sympy科学计算与数据处理(求极限及其它功能)
    Python-sympy科学计算与数据处理(方程,微分,微分方程,积分)
    Python-sympy科学计算与数据处理(数学表达式)
  • 原文地址:https://www.cnblogs.com/grcyh/p/10134341.html
Copyright © 2011-2022 走看看