首页 > 代码库 > BZOJ1975 [SDOI2010] 魔法猪学院
BZOJ1975 [SDOI2010] 魔法猪学院
【问题描述】
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 。
【输出格式】
一行一个数,表示最多可以完成的方式数。输入数据保证至少可以完成一种方式。
【输入样例】
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为实数。
正解:k短路算法(单源最短路+a*算法)
解题报告:这是一个k短路的裸体,拿来练练手,比如,在一个图中,源点是s,汇点是t,k短路的求法是先把所有的边反向,求出所有点到汇点t的最短路,然后从源点开始,用a*算法找路。
1 #include <iostream> 2 #include <iomanip> 3 #include <cstdlib> 4 #include <cstdio> 5 #include <cstring> 6 #include <cmath> 7 #include <string> 8 #include <algorithm> 9 #include <queue> 10 #define RG register 11 #define File(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout) 12 const int N = 10000; 13 const int M = 300000; 14 const int inf = 2147483641; 15 16 using namespace std; 17 18 int nn[M][2],head[N],n,m,nm[M][2],he[N],ans; 19 double w[M],dis[N],gg; 20 bool vis[N]; 21 struct date{ 22 int xh; 23 double s; 24 bool operator < (const date a) const{ 25 return a.s<s; 26 } 27 }; 28 priority_queue<date>d; 29 30 int gi(){ 31 char ch=getchar();int x=0; 32 while(ch<‘0‘ || ch>‘9‘) ch=getchar(); 33 while(ch>=‘0‘ && ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar(); 34 return x; 35 } 36 37 void dijkstra2(){ 38 date k;RG int i; 39 d.push((date){1,dis[1]}); 40 while(!d.empty()){ 41 k=d.top();d.pop(); 42 if (k.xh==n) 43 if (k.s>gg) return; 44 else ans++,gg-=k.s; 45 for (i=head[k.xh]; i; i=nn[i][0]) 46 d.push((date){nn[i][1],k.s-dis[k.xh]+dis[nn[i][1]]+w[i]}); 47 } 48 return; 49 } 50 51 priority_queue<date>h; 52 53 void dijkstra1(){ 54 date a;RG int i; 55 h.push((date){n,0}),dis[n]=0; 56 while(!h.empty()){ 57 a=h.top();h.pop(); 58 if (vis[a.xh]) continue; 59 vis[a.xh]=1; 60 for (i=he[a.xh]; i; i=nm[i][0]) if (dis[nm[i][1]]>dis[a.xh]+w[i]){ 61 dis[nm[i][1]]=dis[a.xh]+w[i]; 62 h.push((date){nm[i][1],dis[nm[i][1]]}); 63 } 64 } 65 return; 66 } 67 68 int main(){ 69 File("1975"); 70 RG int i,l,r; 71 n=gi(),m=gi();scanf("%lf",&gg); 72 for (i=1; i<=m; i++){ 73 l=gi(),r=gi();scanf("%lf",&w[i]); 74 nn[i][1]=r,nn[i][0]=head[l],head[l]=i; 75 nm[i][1]=l,nm[i][0]=he[r],he[r]=i; 76 } 77 for (i=1; i<=n; i++) dis[i]=inf; 78 dijkstra1(); 79 dijkstra2(); 80 printf("%d",ans); 81 return 0; 82 }
BZOJ1975 [SDOI2010] 魔法猪学院