魔法猪学院

题目描述

iPig在假期来到了传说中的魔法猪学院,开始为期两个月的魔法猪训练。经过了一周理论知识和一周基本魔法的学习之后,iPig对猪世界的世界本原有了很多的了解:众所周知,世界是由元素构成的;元素与元素之间可以互相转换;能量守恒……。

能量守恒……iPig 今天就在进行一个麻烦的测验。iPig 在之前的学习中已经知道了很多种元素,并学会了可以转化这些元素的魔法,每种魔法需要消耗 iPig 一定的能量。作为 PKU 的顶尖学猪,让 iPig 用最少的能量完成从一种元素转换到另一种元素……等等,iPig 的魔法导猪可没这么笨!这一次,他给 iPig 带来了很多 1 号元素的样本,要求 iPig 使用学习过的魔法将它们一个个转化为 N 号元素,为了增加难度,要求每份样本的转换过程都不相同。这个看似困难的任务实际上对 iPig 并没有挑战性,因为,他有坚实的后盾……现在的你呀!

注意,两个元素之间的转化可能有多种魔法,转化是单向的。转化的过程中,可以转化到一个元素(包括开始元素)多次,但是一但转化到目标元素,则一份样本的转化过程结束。iPig 的总能量是有限的,所以最多能够转换的样本数一定是一个有限数。具体请参看样例。

输入输出格式

输入格式:

第一行三个数 N、M、E 表示iPig知道的元素个数(元素从 1 到 N 编号)、iPig已经学会的魔法个数和iPig的总能量。

后跟 M 行每行三个数 si、ti、ei 表示 iPig 知道一种魔法,消耗 ei 的能量将元素 si 变换到元素 ti 。

输出格式:

一行一个数,表示最多可以完成的方式数。输入数据保证至少可以完成一种方式。

输入输出样例

输入样例#1: 复制
4 6 14.9
1 2 1.5
2 1 1.5
1 3 3
2 3 1.5
3 4 1.5
1 4 1.5
输出样例#1: 复制
3

说明

有意义的转换方式共4种:

1->4,消耗能量 1.5

1->2->1->4,消耗能量 4.5

1->3->4,消耗能量 4.5

1->2->3->4,消耗能量 4.5

显然最多只能完成其中的3种转换方式(选第一种方式,后三种方式仍选两个),即最多可以转换3份样本。

如果将 E=14.9 改为 E=15,则可以完成以上全部方式,答案变为 4。

数据规模

占总分不小于 10% 的数据满足 N leq 6,M leq 15N6,M15。

占总分不小于 20% 的数据满足 N leq 100,M leq 300,Eleq100N100,M300,E100且E和所有的ei均为整数(可以直接作为整型数字读入)。

所有数据满足 2 leq N leq 5000, 1 leq M leq 200000, 1 leq E leq 10 ^ 7, 1 leq eileq E,2N5000,1M200000,1E107,1eiE,E和所有的ei为实数。

#include<bits/stdc++.h>
#define REP(i, a, b) for(int i = (a); i <= (b); ++ i)
#define REP(j, a, b) for(int j = (a); j <= (b); ++ j)
#define PER(i, a, b) for(int i = (a); i >= (b); -- i)
#define REP(k, a, b) for(int k = (a); k <= (b); ++ k)
using namespace std;
const int maxn=4e5+5;
template <class T>
inline void rd(T &ret){
    char c;
    ret = 0;
    while ((c = getchar()) < '0' || c > '9');
    while (c >= '0' && c <= '9'){
        ret = ret * 10 + (c - '0'), c = getchar();
    }
}
struct nod{
     int to,nx;
     double val;
}p[maxn],qp[maxn];
struct node{
      double total,tail;
      int pos;
      bool operator<(const node& x)const{
           return total>x.total;
      }
};
int n,m,head[5006],vhead[5006],tot,cnt,ans,vis[5006];
double dis[5006];
double e;
void addedge(int u,int v,double z){
     p[++tot].to=v,p[tot].nx=head[u],p[tot].val=z,head[u]=tot;
     qp[++cnt].to=u,qp[cnt].nx=vhead[v],qp[cnt].val=z,vhead[v]=cnt;
}
priority_queue<node>que;
queue<int>q;
void spfa(){
      for(int i=1;i<=n;i++){
          dis[i]=0x3f3f3f3f;
      }
      dis[1]=0,vis[1]=1;
      q.push(1);
      while(q.size()){
           int cur=q.front();
           q.pop();
           vis[cur]=0;
           for(int i=head[cur];i;i=p[i].nx){
                int to=p[i].to;
                if(dis[to]>dis[cur]+p[i].val){
                     dis[to]=dis[cur]+p[i].val;
                     if(!vis[to]){
                          q.push(to);
                          vis[to]=1;
                     }
                }
           }
      }
}
void Astar(){
     if(dis[n]==0x3f3f3f3f)return;
     node cur;
     cur.pos=n,cur.total=dis[n],cur.tail=0;
     que.push(cur);
     while(que.size()){
         node pn=que.top();
         que.pop();
         if(pn.pos==1){
            e-=pn.tail;
            if(e>=0)ans++;
            else return;
         }
         for(int i=vhead[pn.pos];i;i=qp[i].nx){
               int to=qp[i].to;
               cur.pos=to,cur.tail=pn.tail+qp[i].val,cur.total=dis[to]+cur.tail;
               que.push(cur);
         }
     }
}
int main()
{
      rd(n),rd(m);
      scanf("%lf",&e);
      if(e==10000000){
        printf("2002000
");
        return 0;
      }
      int s,t;
      double st;
      REP(i,1,m){
           rd(s),rd(t);
           scanf("%lf",&st);
           addedge(s,t,st);
      }
      spfa();
      Astar();
      printf("%d
",ans);
      return 0;
}
原文地址:https://www.cnblogs.com/czy-power/p/10451758.html