• bzoj 1975 [Sdoi2010]魔法猪学院


    1975: [Sdoi2010]魔法猪学院

    Time Limit: 10 Sec  Memory Limit: 64 MB
    Submit: 1758  Solved: 557
    [Submit][Status][Discuss]

    Description

    iPig在假期来到了传说中的魔法猪学院,开始为期两个月的魔法猪训练。经过了一周理论知识和一周基本魔法的学习之后,iPig对猪世界的世界本原有了很多的了解:众所周知,世界是由元素构成的;元素与元素之间可以互相转换;能量守恒……。 能量守恒……iPig 今天就在进行一个麻烦的测验。iPig 在之前的学习中已经知道了很多种元素,并学会了可以转化这些元素的魔法,每种魔法需要消耗 iPig 一定的能量。作为 PKU 的顶尖学猪,让 iPig 用最少的能量完成从一种元素转换到另一种元素……等等,iPig 的魔法导猪可没这么笨!这一次,他给 iPig 带来了很多 1 号元素的样本,要求 iPig 使用学习过的魔法将它们一个个转化为 N 号元素,为了增加难度,要求每份样本的转换过程都不相同。这个看似困难的任务实际上对 iPig 并没有挑战性,因为,他有坚实的后盾……现在的你呀! 注意,两个元素之间的转化可能有多种魔法,转化是单向的。转化的过程中,可以转化到一个元素(包括开始元素)多次,但是一但转化到目标元素,则一份样本的转化过程结束。iPig 的总能量是有限的,所以最多能够转换的样本数一定是一个有限数。具体请参看样例。

    Input

    第一行三个数 N、M、E 表示iPig知道的元素个数(元素从 1 到 N 编号)、iPig已经学会的魔法个数和iPig的总能量。 后跟 M 行每行三个数 si、ti、ei 表示 iPig 知道一种魔法,消耗 ei 的能量将元素 si 变换到元素 ti 。

    Output

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

    Sample Input

    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

    Sample Output

    3

    HINT

    样例解释
    有意义的转换方式共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为实数。

    Source

    [Submit][Status][Discuss]


    HOME Back

    ————————————我是分割线——————————————

    题目大意:给出一张无向图,给出一个数值m,求出从1到N的前k短路的长度和>=数值m。

    思路:

    思路很简单,就是按顺序求出这张图的前k短路,然后当m减成负数的时候就返回。

    k短路的求解要用到A*算法

    A*算法的启发式函数f(n)=g(n)+h(n)

    g(n)是状态空间中搜索到n所花的实际代价

    h(n)是n到结束状态最佳路径的估计代价

    关于h(n)的选取,当h(n)<实际代价时,搜索慢但可出解;h(n)=实际代价时,正确率与效率最高;h(n)>实际代价,快但只能得到近似解。

    但在k短路问题中,h(n)是可以选到准确值的,就是n到结束节点的最短路,预处理时从结束节点做一次单源最短路即可。

    按广搜的方式扩展节点,每次优先扩展f(n)最小的节点。

    第i次扩展到目标节点,代表找到了第i短路。

    正确性什么的很好理解。

    k短路关于A*部分代码很简洁,用优先队列维护。

    注意!不能使用priority_queue,否则你会死的很惨。。

      1 /*
      2     Problem:
      3     OJ:
      4     User:    S.B.S.
      5     Time:
      6     Memory:
      7     Length:
      8 */
      9 #include<iostream>
     10 #include<cstdio>
     11 #include<cstring>
     12 #include<cmath>
     13 #include<algorithm>
     14 #include<queue>
     15 #include<cstdlib>
     16 #include<iomanip>
     17 #include<cassert>
     18 #include<climits>
     19 #include<functional>
     20 #include<bitset>
     21 #include<vector>
     22 #include<list>
     23 #include<map>
     24 #define F(i,j,k) for(int i=j;i<=k;i++)
     25 #define M(a,b) memset(a,b,sizeof(a))
     26 #define FF(i,j,k) for(int i=j;i>=k;i--)
     27 #define maxn 100001
     28 #define inf 0x3f3f3f3f
     29 #define maxm 1001
     30 #define mod 998244353
     31 //#define LOCAL
     32 using namespace std;
     33 int read(){
     34     int x=0,f=1;char ch=getchar();
     35     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     36     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
     37     return x*f;
     38 }
     39 int n,m;
     40 double d[maxn];
     41 struct EDGE
     42 {
     43     int u;
     44     int v;
     45     double w;
     46     int next;
     47 }e1[maxn],e2[maxn];
     48 int tot1,tot2;
     49 int head1[maxn],head2[maxn];
     50 inline int addedge1(int u,int v,double w)
     51 {
     52     tot1++;
     53 //    e1[tot1].u=u;
     54     e1[tot1].v=v;
     55     e1[tot1].w=w;
     56     e1[tot1].next=head1[u];
     57     head1[u]=tot1;
     58 }
     59 inline int addedge2(int u,int v,double w)
     60 {
     61     tot2++;
     62 //    e2[tot2].u=u;
     63     e2[tot2].v=v;
     64     e2[tot2].w=w;
     65     e2[tot2].next=head2[u];
     66     head2[u]=tot2;
     67 }
     68 struct NODE
     69 {
     70     double f;
     71     double g;
     72     int o;
     73     bool operator < (const NODE & a) 
     74         const{return f<a.f;} 
     75 };
     76 double c;
     77 bool inq[maxn];
     78 inline int spfa()
     79 {
     80     queue<int> q;
     81     M(d,127);
     82     d[n]=0;inq[n]=1;
     83     q.push(n);
     84     while(!q.empty())
     85     {
     86         int u=q.front();q.pop();
     87         for(int i=head2[u];i;i=e2[i].next)
     88         {
     89             int v=e2[i].v;
     90             if(d[v]>d[u]+e2[i].w){
     91 //                cout<<d[u]<<" "<<e2[i].w<<" "<<d[u]+e2[i].w<<"*********"<<endl;
     92                 d[v]=d[u]+e2[i].w;
     93 //                cout<<d[v]<<" &&&&&&"<<endl;
     94                 if(!inq[v]){
     95                     q.push(v);
     96                     inq[v]=1;
     97                 }
     98             }
     99         }
    100         inq[u]=0;
    101     }
    102 }
    103 int ans,size;
    104 NODE q[2000000];
    105 inline int push(NODE x)
    106 {
    107     int now,next;
    108     q[++size]=x;
    109     now=size;
    110     while(now>1){
    111         next=now>>1;
    112         if(q[next]<q[now]) break;
    113         swap(q[now],q[next]);
    114         now=next;
    115     }
    116 }
    117 inline NODE pop()
    118 {
    119     int now,next;
    120     NODE cur;
    121     cur=q[1];
    122     q[1]=q[size--];
    123     now=1;
    124     while((now<<1)<=size){
    125         next=now<<1;
    126         if(next<size&&q[next+1]<q[next]) next++;
    127         if(q[now]<q[next]) break;
    128         swap(q[now],q[next]);
    129         now=next;
    130     }
    131     return cur;
    132 }
    133 inline void astar()
    134 {
    135     push((NODE){d[1],0,1});
    136     while(size){
    137         NODE x=pop();
    138         for(int i=head1[x.o];i;i=e1[i].next){
    139             int v=e1[i].v;
    140             push((NODE){x.g+e1[i].w+d[v],x.g+e1[i].w,v});
    141         }
    142         if(x.o==n){
    143             c-=x.f;
    144             if(c<0) return;
    145             ans++;
    146         }
    147     }
    148 }
    149 int main()
    150 {
    151     std::ios::sync_with_stdio(false);//cout<<setiosflags(ios::fixed)<<setprecision(1)<<y;
    152     #ifdef LOCAL
    153     freopen("data.in","r",stdin);
    154     freopen("data.out","w",stdout);
    155     #endif
    156     cin>>n>>m>>c;
    157     int u,v;
    158     double w;
    159     F(i,1,m){
    160         cin>>u>>v>>w;
    161 //        cout<<u<<" "<<v<<" "<<w<<endl;
    162         addedge1(u,v,w);
    163 //        cout<<e1[i].w<<" ";
    164         addedge2(v,u,w);
    165 //        cout<<e2[i].w<<endl;
    166     }
    167     spfa();
    168 //    F(i,1,n) cout<<d[i]<<" ";cout<<endl;
    169     astar();
    170     cout<<ans<<endl;
    171     return 0;
    172 }
    View Code
  • 相关阅读:
    有上下界的可行流
    NOIP模拟——change
    NOIP模拟 ———number(假的数位dp)
    18.8.18NOIP模拟。。。。Snow
    字符串算法(KMP,Trie树,AC自动机)
    BZOJ4293 Siano
    NOIP2017 DAY2 T1
    AtCoder Grand Contest 023 D GO Home
    浅谈SPFA(队列优化的Bellman-Ford算法)
    最短路最基本算法———Floyd算法
  • 原文地址:https://www.cnblogs.com/SBSOI/p/5913647.html
Copyright © 2020-2023  润新知