纪中OJ 5177【NOIP2017提高组模拟6.28】Trevel

动态SPFA水题,和之前某道魔法森林相似

我们先存边,然后按L排个序,之后在将每一条边加入,每加入一条边,就以当前边的两个端点为起点,做一次双源最短路,不难发现,加入这条边后,这两个点最可能更新其他点

初始化时除了1之外,其他点的dis=0,dis[1]=inf,然后我们按照R来做最长路,考虑点u,v,边 e,dis[v]可能的取值有三种,v之前被更新过,所以有一个dis[v],考虑题目的限制,这次路线的的区间是最大的L~最小的R,因为我们按照L从小到达排序,所以图中最大的L就是刚刚加入的边,所以不需要考虑L,那么考虑R,在到达u之前,可能存在一条边p是到达u必须要走的边且是必须边中最小的(自己感性理解,必须边是一条链,那么必须要走这条最小的边,那么R只能是这条边的R),val[p]<val[e],我们之前保证dis[v]<dis[u],那么显然dis[v]=dis[u]因为e这条边比dis[u]大,所以这条边的R也是dis[u],然后另一种情况val[p]>val[e],那么在这条边之前没有比这条边R小的,但这条边又是u->v的必须边,所以dis[v]只能等于val[e],所以我们得到在跑SPFA时,更新条件为

if (dis[v]>min(dis[u],val[e])) dis[v]>min(dis[u],val[e]);

然后记录SPFA中max(dis[n]-SPFA前加入的边的L)

代码

//By AcerMo
#include<cmath>
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int M=5050;
struct edge
{
	int x,y,w1,w2;
	bool friend operator < (edge a,edge b)
	{
		return a.w1<b.w1;
	}
}e[M*2];
int n,m;
int dis[M],vis[M];
int cnt,to[M*2],nxt[M*2],head[M*2],co1[M*2],co2[M*2];
queue<int>q;
inline int read()
{
	int x=0;char ch=getchar();
	while (ch<'0'||ch>'9') ch=getchar();
	while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
	return x;
}
inline void add(int x,int y,int w,int c)
{
	to[++cnt]=y;nxt[cnt]=head[x];co1[cnt]=w;co2[cnt]=c;head[x]=cnt;
	to[++cnt]=x;nxt[cnt]=head[y];co1[cnt]=w;co2[cnt]=c;head[y]=cnt;
	return ;
}
inline void SPFA(int st,int ed)
{
	q.push(st);q.push(ed);
	while (q.size())
	{
		int u=q.front();q.pop();vis[u]=0;
		for (int i=head[u];i;i=nxt[i])
		{
			if (dis[to[i]]<min(dis[u],co2[i]))
			{
				dis[to[i]]=min(dis[u],co2[i]);
				if (!vis[to[i]])
					vis[to[i]]=1,q.push(to[i]);
			}
		}
	}
	return ;
}
signed main()
{
	n=read();m=read();int ans=0,l=0,r=0;
	for (int i=1;i<=m;i++)
		e[i].x=read(),e[i].y=read(),e[i].w1=read(),e[i].w2=read();
	sort(e+1,e+m+1);dis[1]=2e9;q.push(1);
	for (int i=1;i<=m;i++)
	{
		add(e[i].x,e[i].y,e[i].w1,e[i].w2);SPFA(e[i].x,e[i].y);
		if (ans<dis[n]-e[i].w1) ans=dis[n]-e[i].w1,l=e[i].w1,r=dis[n];
	}
	cout<<ans+1<<endl;
	for (int i=l;i<r;i++) cout<<i<<" ";cout<<r;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/ACerAndAKer/article/details/81605540