bzoj 1975 [Sdoi2010]魔法猪学院(k短路)

 

题目描述

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

 

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

 

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

 

输入格式(magic.in)

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

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

 

输出格式(magic.out)

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

 

样例输入

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

 

样例输出

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 <= 6,M<=15。

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

所有数据满足 2 <= N <= 5000,1 <= M <= 200000,1<=E<=107,1<=ei<=E,E和所有的ei为实数。

 

【思路】

 

       A*算法解k短路

       启发式函数f(n)=g(n)+h(n)

       g是到达当前状态的实际代价,h是估计代价。当h取得比较小的时候,能保证正确性但时间比较慢,当h取得比较大的时候,速度快但正确不能保证。

       一个暴力算法是将到目前为止的距离放入堆里,然后第k次拓展到n求出k短路。这里可以看作h0 ,前边说了,比较慢。

       这里取每个点到n的最短路为估计代价h

       把启发函数放到一个堆里,每次拿出队首拓展求出启发函数后再放入堆里。第k次拓展到n时,就得到了1..nk短路。

       这样只要不断求k短路直到把e用完。

 

       据说STLMLE,我没试过<_<,手写一个heap

 

【代码】

  1 #include<cstdio>
  2 #include<queue>
  3 #include<vector>
  4 #include<cstring>
  5 using namespace std;
  6 
  7 const int N = 5005;
  8 const double INF = 1e9;
  9 
 10 struct Edge { int v; double w;
 11 };
 12 struct Node {
 13     double f; int id;
 14     bool operator < (const Node& rhs) const{
 15         return f<rhs.f;
 16     }
 17 };
 18 struct Heap {
 19     int sz,now,next; Node ans;
 20     Node N[2000000];
 21     Heap() { sz=0; }
 22     int empty() { return sz<=0; }
 23     void push(Node x) {
 24         N[++sz]=x;
 25         now=sz;
 26         while(now>1) {
 27             next=now>>1;
 28             if(N[next]<N[now]) break;
 29             swap(N[next],N[now]);
 30             now=next;
 31         }
 32     }
 33     Node pop() {
 34         ans=N[1];
 35         N[1]=N[sz--];
 36         now=1;
 37         while((now<<1)<=sz) {
 38             next=now<<1;
 39             if(next<sz && N[next+1]<N[next]) next++;
 40             if(N[now]<N[next]) break;
 41             swap(N[now],N[next]);
 42             now=next;
 43         }
 44         return ans;
 45     }
 46 }hp;
 47 
 48 vector<Edge> g[N],G[N];
 49 queue<int> q;
 50 
 51 int n,m,ans;
 52 int inq[N]; double e,dis[N];
 53 
 54 void spfa() {
 55     for(int i=1;i<=n;i++) dis[i]=INF;
 56     dis[n]=0; inq[n]=1; q.push(n);
 57     while(!q.empty()) {
 58         int u=q.front(); q.pop(); 
 59         inq[u]=0;
 60         for(int i=0;i<G[u].size();i++) {
 61             int v=G[u][i].v;
 62             if(dis[v]>dis[u]+G[u][i].w) {
 63                 dis[v]=dis[u]+G[u][i].w;
 64                 if(!inq[v])
 65                     inq[v]=1,
 66                     q.push(v);
 67             }
 68         }
 69     }
 70 }
 71 
 72 void astar() {
 73     hp.push((Node){dis[1],1});
 74     while(!hp.empty()) {
 75         Node qr=hp.pop(); int u=qr.id;
 76         for(int i=0;i<g[u].size();i++) {
 77             int v=g[u][i].v;
 78             hp.push((Node){qr.f-dis[u]+g[u][i].w+dis[v],v});
 79         }
 80         if(u==n) {
 81             e-=qr.f;
 82             if(e<0) break;
 83             else ans++;
 84         }
 85     }
 86 }
 87 
 88 int main() {
 89     scanf("%d%d%lf",&n,&m,&e);
 90     int u,v; double w;
 91     for(int i=0;i<m;i++) {
 92         scanf("%d%d%lf",&u,&v,&w);
 93         g[u].push_back((Edge){v,w});
 94         G[v].push_back((Edge){u,w});
 95     }
 96     spfa();
 97     astar();
 98     printf("%d",ans);
 99     return 0;
100 }

 

你可能感兴趣的:(bzoj 1975 [Sdoi2010]魔法猪学院(k短路))