BZOJ1975 SDOI2010魔法猪学院
就是个A*,具体原理可以参考VANE的博文。
正解要手写堆,会被卡常,也许哪天我筋搭错了写一回吧。
1 #include<bits/stdc++.h> 2 #define r register 3 using namespace std; 4 const int N=5005,eps=1e-7,M=400050; 5 int head[N],cnt=-1,sum,n,m,to[M],nex[M]; 6 double d[N],E,ww[M];bool v[N]; 7 inline void add(int x,int y,double w) 8 { 9 to[++cnt]=y;ww[cnt]=w; 10 nex[cnt]=head[x];head[x]=cnt; 11 to[++cnt]=x;ww[cnt]=w; 12 nex[cnt]=head[y];head[y]=cnt; 13 } 14 struct data{ 15 int u;double g,h; 16 bool operator<(const data &b)const{ 17 return g==b.g?h>b.h:g>b.g; 18 } 19 }t; 20 inline int read() 21 { 22 int x=0,f=1;char ch=getchar(); 23 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 24 while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar(); 25 return x*f; 26 } 27 void spfa() 28 { 29 queue<int>Q; 30 Q.push(n); 31 memset(d,127,sizeof(d)); 32 d[n]=0;v[n]=1; 33 while(!Q.empty()) 34 { 35 int x=Q.front();Q.pop();v[x]=0; 36 for(r int i=head[x];i!=-1;i=nex[i]) 37 { 38 if(i&1==0)continue; 39 int y=to[i]; 40 if(d[y]<=d[x]+ww[i])continue; 41 d[y]=d[x]+ww[i]; 42 if(!v[y]) 43 { 44 v[y]=1;Q.push(y); 45 } 46 } 47 } 48 return; 49 } 50 int arr[N]; 51 void work() 52 { 53 priority_queue<data>Q; 54 t.u=1;t.h=0;t.g=t.h+d[1]; 55 Q.push(t);int K=E/d[1]; 56 while(!Q.empty()&&E+eps>0) 57 { 58 data x=Q.top();Q.pop(); 59 if(x.g>E)break; 60 arr[x.u]++; 61 if(x.u==n) 62 { 63 sum++;E-=x.g;continue; 64 } 65 if(arr[x.u]>K)break; 66 for(r int i=head[x.u];i!=-1;i=nex[i]) 67 { 68 if(i&1)continue; 69 data y;y.u=to[i];y.h=x.h+ww[i];y.g=y.h+d[y.u]; 70 if(y.g>E)continue; 71 Q.push(y); 72 } 73 } 74 printf("%d\n",sum); 75 return; 76 } 77 int main() 78 { 79 n=read();m=read(); 80 scanf("%lf",&E); 81 int x,y;double w; 82 memset(head,-1,sizeof(head)); 83 for(r int i=1;i<=m;++i) 84 { 85 x=read();y=read(); 86 scanf("%lf",&w); 87 add(x,y,w); 88 } 89 spfa(); 90 work(); 91 return 0; 92 }
生命中真正重要的不是你遭遇了什么,而是你记住了哪些事,又是如何铭记的。