• 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
    ",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 }
  • 相关阅读:
    01 Java基础第一天
    2019牛客暑期多校训练营(第七场)J A+B problem
    SDNU 1477.矩形面积交(思维)
    SDNU 1194.传纸条(DP)&& 1032.机器人
    SDNU 1280.就问你慌不慌(高精度)
    POJ 2528 Mayor's posters(线段树+离散化)
    HDU 1698 Just a Hook(线段树区间赋值)
    POJ 3468 A Simple Problem with Integers (区间加区间查找)
    HDU 1754 I Hate It(线段树单点更改、区间查找最大值)
    HDU 1166 敌兵布阵(线段树单点加区间查询)
  • 原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8364931.html
Copyright © 2020-2023  润新知