zoukankan      html  css  js  c++  java
  • 2019.10.29 CSP%您赛第四场t2

    我太菜了我竟然不会分层图最短路


    迷路(star)

    【题目描述】
    (cxm)(ns) 星系迷路了,情急之下,他找到了你。现在,解救 (cxm) 的重任就落在了
    你的肩上了。
    (ns) 星系有 (n) 颗星球,编号为 (1)(n) 的整数。星球之间由 (m) 条单向的时空隧道相
    连。经过每个时空隧道要花费一定的时间。(cxm) 的飞船最多可以存储 (max)(\_)(energy) 的能
    量,经过有些时空隧道会损失能量,而其他的会增加能量。飞船不能通过损失能量数超
    过当前能量或者增加能量后飞船能量超过 (max\_energy) 的时空隧道。
    现在,(cxm) 的飞船在编号为 (1) 的星球,飞船剩余的能量为 (max\_energy) 的一半。你
    需要计算出到编号为 (n) 的星球的最短时间。
    【输入格式】
    从文件 (star.in) 中读入数据。
    第一行三个正整数 (n,m)(max\_energy)
    接下来 (m) 行,每行 (3) 个正整数 (u,v,time)(1) 个整数 (energy)。表示从编号为 (u) 的星
    球到编号为 (v) 的星球有一条时空隧道,经过这个隧道花费的时间为 (time)。如果 (energy)
    为正数,则表示通过会增加 (energy) 的能量,否则表示通过会损失 (−energy) 的能量。保
    证,(1leq u,vleq n,1leq timeleq 10^4 ,−100leq energyleq 100)
    每行两个数之间均用空格隔开。
    【输出格式】
    输出到文件 (star.out) 中。
    输出一行,一个正整数,表示到达的最短时间。数据保证有解。
    【样例输入】
    4 6 4
    1 4 100 0
    1 2 5 -1
    2 3 3 2
    3 2 1 -1
    3 4 5 -4
    3 4 10 -3

    【样例输出】
    17
    【子任务】
    每个测试点的数据规模如下

    测试点 (n=) (m=) (max\_energy) 数据特点
    (1) (5) (11) (4) 无特殊性质
    (2) (8) (16) (4) 无特殊性质
    (3) (10) (21) (6) 无特殊性质
    (4,5,6) (50) (2000) (10^2) 所有的(energy)均为正
    (7,8,9,10) (50) (2000) (50) 无特殊性质

    容易想到最短路。但是因为有(energy)限制的存在,所以不能跑简单的最短路。
    我记得有过一个(OIdalao)讲过一句话。
    ——如果dp不知道一个状态怎么存,就再加一维。
    所以对于正常的一维(SPFA)我们将它加一维,表示当前的能量是多少。最后枚举所有可能的终点能量值即可。
    上代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<queue>
    #include<vector>
    #include<utility>
    #define rep(i,a,n) for(int i=a;i<=n;i++)
    #define dep(i,n,a) for(int i=n;i>=a;i--)
    #define int long long
    using namespace std;
    queue<pair<int,int> > q;
    int n,m,max_energy,dis[55][155],inq[55][55],ans,num,head[55];
    struct edge
    {
    	int u,v,time,energy,nxt;
    }e[100050];
    inline int read()
    {
    	int x=0,f=1;
    	char ch=getchar();
    	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    	while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    	return x*f;
    }
    void add(int u,int v,int t,int en)
    {
    	e[++num].u=u;e[num].v=v;
    	e[num].time=t;e[num].energy=en;
    	e[num].nxt=head[u];head[u]=num;
    }
    signed main()
    {
    	memset(head,-1,sizeof head);
    	memset(dis,127,sizeof dis);
    	n=read(),m=read(),max_energy=read();
    	int u,v,t,en;
    	rep(i,1,m)
    	{
    		u=read(),v=read(),t=read(),en=read();
    		add(u,v,t,en);
    	}
    	q.push(make_pair(1,max_energy/2));
    	ans=dis[0][0];
    	dis[1][max_energy/2]=0;
    	inq[1][max_energy/2]=1;
    	while(!q.empty())
    	{
    		int x=q.front().first;
    		int ee=q.front().second;
    		inq[x][ee]=0;
    		q.pop();
    		for(int st=head[x];~st;st=e[st].nxt)
    		{
    			int y=e[st].v;
    			int ene=e[st].energy;
    			if(ee+ene>max_energy||ee+ene<0)continue;
    			if(dis[x][ee]+e[st].time<dis[y][ee+ene])
    			{
    				dis[y][ee+ene]=dis[x][ee]+e[st].time;
    				if(!inq[y][ee+ene])
    				{
    					q.push(make_pair(y,ee+ene));
    					inq[y][ee+ene]=1;
    				}
    			}
    		}
    	}
    	rep(i,0,max_energy)
    		ans=min(ans,dis[n][i]);
    	printf("%lld",ans);
    	return 0;
    }
    
  • 相关阅读:
    linux系统性能监控常用命令
    如何在windows的DOS窗口中正常显示中文(UTF-8字符)
    在Windows的CMD中如何设置支持UTF8编码?
    设置cmd的codepage的方法
    Oracle字符集转换
    移动端跨平台开发的深度解析
    类型擦除是抽象泛型的实例化的过程
    FP又称为Monadic Programming
    深入剖析Swift性能优化
    真实世界中的 Swift 性能优化
  • 原文地址:https://www.cnblogs.com/qxds/p/11766743.html
Copyright © 2011-2022 走看看