bzoj 3575: [Hnoi2014]道路堵塞

Description

A 国有N座城市,依次标为1到N。同时,在这N座城市间有M条单向道路,每条道路的长度是一个正整数。现在,A国交通部指定了一条从城市1到城市N的路径, 并且保证这条路径的长度是所有从城市1到城市N的路径中最短的。不幸的是,因为从城市1到城市N旅行的人越来越多,这条由交通部指定的路径经常发生堵塞。 现在A国想知道,这条路径中的任意一条道路无法通行时,由城市1到N的最短路径长度是多少。

Input

输入文件第一行是三个用空格分开的正整数N、M和L,分别表示城市数目、单向道路数目和交通部指定的最短路径包含多少条道路。

按下来M行,每行三个用空格分开的整数a、b和c,表示存在一条由城市a到城市b的长度为c的单向道路。这M行的行号也是对应道路的编号,即其中第1行对
应的道路编号为1,第2行对应的道路编号为2,…,第M行对应的道路编号为M。最后一行为L个用空格分开的整数sp(1)…,,sp(L),依次表示从城
市1到城市N的由交通部指定的最短路径上的道路的编号。

Output

输出文件包含L行,每行为一个整数,第i行(i=1,2…,,L)的整数表示删去编号为sp(i)的道路后从城市1到城市N的最短路径长度。如果去掉后没有从城市1到城市N的路径,则输出一1。

真的是连SPFA都不会...

根据玄学猜想:删掉最短路上的一条边后的最短路一定是由三段组成:

最短路上的一段 1--x,非最短路上的一段x--y,以及最短路上的一段y--n;

然后对于每次删掉一条连接(u,v)的边我们就把u放入队列中,并强制不走删掉的那一条边,拿u来松弛其它点到1的最短路

如果走到了最短路上的某个点x,并且该点在最短路上的标号比u大(在u后面),把这个点放入堆中即可

这个我们只需要维护好两个数组,一个1到每个最短路上的点的距离,一个是每个最短路上的点到n的距离

之后就可以愉快的跑SPFA了

// MADE BY QT666
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=700050;
int gi()
{
    int x=0,flag=1;
    char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘) flag=-1;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar();
    return x*flag;
}
int head[N],to[N],nxt[N],c[N],cnt;
int pre[N],pre2[N],id[N],to2[N],n,m,L;
int a[N],vis[N],vis2[N],q[N*10],q2[N*10],dis[N];
struct data{
    int id,dis;
    bool operator < (const data &a) const {return a.dis<dis;}
}b[N];
priority_queue<data>Q;
void lnk(int x,int y,int z){
    to[++cnt]=y,c[cnt]=z,nxt[cnt]=head[x],head[x]=cnt;
}
void spfa(int x,int y,int z){
    dis[x]=pre[id[x]];int t=0,sum=1,tail=0;q[0]=x;q2[++tail]=x;
    vis[x]=1;
    for(int i=1;i<=L+1;i++) vis2[to2[i]]=0;
    while(t<sum){
	int now=q[t++];vis[now]=0;
	for(int i=head[now];i;i=nxt[i]){
	    if(i!=y){
		int u=to[i];
		if(id[u]>z){
		    if(!vis2[u]){
			b[u].dis=dis[now]+c[i]+pre2[id[u]];
			b[u].id=id[u];vis2[u]=1;
			q2[++tail]=u;
		     }
		    else b[u].dis=min(b[u].dis,dis[now]+c[i]+pre2[id[u]]);
		}
		else{
		    if(dis[u]>dis[now]+c[i]){
			dis[u]=dis[now]+c[i];
			if(!vis[u]) vis[u]=1,q[sum++]=u;
		    }
		}
	    }
	}
    }
    while(tail) Q.push(b[q2[tail]]),tail--;
}
int main(){
    n=gi(),m=gi(),L=gi();
    for(int i=1;i<=m;i++){
	int x=gi(),y=gi(),z=gi();
	lnk(x,y,z);
    }
    to2[1]=id[1]=1;
    for(int i=1;i<=L;i++){
	a[i]=gi();
	to2[i+1]=to[a[i]];
	id[to[a[i]]]=i+1;
    }
    for(int i=1;i<=L;i++) pre[i+1]=pre[i]+c[a[i]];
    for(int i=L;i>=1;i--) pre2[i]=pre2[i+1]+c[a[i]];
    memset(dis,127,sizeof(dis));
    for(int i=1;i<=L;i++){
	spfa(to2[i],a[i],i);
	while(!Q.empty()&&Q.top().id<=i) Q.pop();
	if(Q.empty()) puts("-1");
	else printf("%d\n",Q.top().dis);
    }
}
时间: 2024-10-26 09:53:22

bzoj 3575: [Hnoi2014]道路堵塞的相关文章

bzoj3575 [Hnoi2014]道路堵塞

Description A 国有N座城市,依次标为1到N.同时,在这N座城市间有M条单向道路,每条道路的长度是一个正整数.现在,A国交通部指定了一条从城市1到城市N的路径, 并且保证这条路径的长度是所有从城市1到城市N的路径中最短的.不幸的是,因为从城市1到城市N旅行的人越来越多,这条由交通部指定的路径经常发生堵塞. 现在A国想知道,这条路径中的任意一条道路无法通行时,由城市1到N的最短路径长度是多少. Input 输入文件第一行是三个用空格分开的正整数N.M和L,分别表示城市数目.单向道路数目

[HNOI2014]道路堵塞

题目描述 A国有N座城市,依次标为1到N.同时,在这N座城市间有M条单向道路,每条道路的长度是一个正整数.现在,A国交通部指定了一条从城市1到城市N的路径,并且保证这条路径的长度是所有从城市1到城市N的路径中最短的.不幸的是,因为从城市1到城市N旅行的人越来越多,这条由交通部指定的路径经常发生堵塞.现在A国想知道,这条路径中的任意一条道路无法通行时,由城市1到N的最短路径长度是多少. 输入输出格式 输入格式: 输入文件第一行是三个用空格分开的正整数N.M和L,分别表示城市数目.单向道路数目和交通

BZOJ3575 HNOI2014 道路阻塞

3575: [Hnoi2014]道路堵塞 Time Limit: 10 Sec  Memory Limit: 128 MB Description A国有N座城市,依次标为1到N.同时,在这N座城市间有M条单向道路,每条道路的长度是一个正整数.现在,A国交通部指定了一条从城市1到城市N的路径,并且保证这条路径的长度是所有从城市1到城市N的路径中最短的.不幸的是,因为从城市1到城市N旅行的人越来越多,这条由交通部指定的路径经常发生堵塞.现在A国想知道,这条路径中的任意一条道路无法通行时,由城市1到

BZOJ 3575 道路堵塞

Description A国有N座城市,依次标为1到N.同时,在这N座城市间有M条单向道路,每条道路的长度是一个正整数.现在,A国交通部指定了一条从城市1到城市N的路径,并且保证这条路径的长度是所有从城市1到城市N的路径中最短的.不幸的是,因为从城市1到城市N旅行的人越来越多,这条由交通部指定的路径经常发生堵塞.现在A国想知道,这条路径中的任意一条道路无法通行时,由城市1到N的最短路径长度是多少. Input 输入文件第一行是三个用空格分开的正整数N.M和L,分别表示城市数目.单向道路数目和交通

bzoj 3572 [Hnoi2014]世界树(虚树+DP)

3572: [Hnoi2014]世界树 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 645  Solved: 362[Submit][Status][Discuss] Description 世界树是一棵无比巨大的树,它伸出的枝干构成了整个世界.在这里,生存着各种各样的种族和生灵,他们共同信奉着绝对公正公平的女神艾莉森,在他们的信条里,公平是使世界树能够生生不息.持续运转的根本基石.     世界树的形态可以用一个数学模型来描述:世界树中有n个

【BZOJ 1018】 [SHOI2008]堵塞的交通traffic

1018: [SHOI2008]堵塞的交通traffic Time Limit: 3 Sec  Memory Limit: 162 MB Submit: 1811  Solved: 580 [Submit][Status] Description 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常奇特,整个国家的交通系统可以被看成是一个2行C列的矩形网格,网格上的每个点代表一个城市,相邻的城市之间有一条道路,所以总共有2C个城市和3C-2条道路. 小人国的交通状况非常槽糕.有

bzoj 2435: [Noi2011]道路修建 树上 dp

2435: [Noi2011]道路修建 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/problem.php?id=2435 Description 在 W 星球上有 n 个国家.为了各自国家的经济发展,他们决定在各个国家 之间建设双向道路使得国家之间连通.但是每个国家的国王都很吝啬,他们只愿 意修建恰好 n – 1条双向道路. 每条道路的修建都要付出一定的费用, 这个费用等于道路长度乘

[BZOJ 3995] [SDOI2015] 道路修建 【线段树维护连通性】

题目链接:BZOJ - 3995 题目分析 这道题..是我悲伤的回忆.. 线段树维护连通性,与 BZOJ-1018 类似,然而我省选之前并没有做过  1018,即使它在 ProblemSet 的第一页. 更悲伤的是,这道题有 40 分的暴力分,写个 Kruskal 就可以得到,然而我写了个更快的 DP . 这本来没有什么问题,然而我的 DP 转移少些了一种情况,于是...爆零.没错,省选前20名可能就我没有得到这 40 分? 不想再多说什么了...希望以后不要再这样 SB 了,如果以后还有机会的

【dfs】【NOI 2011】【bzoj 2435】道路修建

2435: [Noi2011]道路修建 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 2645 Solved: 825 Description 在 W 星球上有 n 个国家.为了各自国家的经济发展,他们决定在各个国家之间建设双向道路使得国家之间连通.但是每个国家的国王都很吝啬,他们只愿意修建恰好 n – 1条双向道路. 每条道路的修建都要付出一定的费用, 这个费用等于道路长度乘以道路两端的国家个数之差的绝对值.例如,在下图中,虚线所示道路两端分别