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 }

 

posted @ 2018-01-27 09:59  大奕哥&VANE  阅读(163)  评论(0编辑  收藏  举报