正题
题目链接:https://www.cometoj.com/contest/73/problem/E?problem_id=4124
题目大意
给出\(n\)个点\(m\)条边的一张有向图,边有边权,\(q\)次询问从点\(1\)走到点\(x\)的所有路径(可以重复经过任何点包括点\(x\))中极差最大是多少。
\(1\leq n\leq 2\times 10^5,1\leq m\leq 5\times 10^5\)
解题思路
首先肯定要\(tarjan\)缩点,然后考虑怎么统计极差。
考虑到极差其实到某个位置的时候就已经不会再改变了,而且这个到这个位置的路径一定是作为最小值或者最大值的。
所以我们可以维护一个路径上的最大值/最小值和最大极差,然后每次考虑新的转移会不会更新极差就可以了。
时间复杂度:\(O(n+m)\)
CometOJ评测机炸了,代码没测就当过了吧...
code
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#define mp(x,y) make_pair(x,y)
using namespace std;
const int N=2e5+10;
int n,m,t,cnt,dfn[N],low[N],col[N],in[N];
int mi[N],mx[N],Mi[N],Mx[N],ans[N];
stack<int> s;queue<int> q;bool ins[N];
vector<pair<int,int> > G[N],T[N];
void tarjan(int x){
dfn[x]=low[x]=++cnt;
ins[x]=1;s.push(x);
for(int i=0;i<G[x].size();i++){
int y=G[x][i].first;
if(!dfn[y]){
tarjan(y);
low[x]=min(low[x],low[y]);
}
else if(ins[y])
low[x]=min(low[x],dfn[y]);
}
if(dfn[x]==low[x]){
while(s.top()!=x){
col[s.top()]=x;
ins[s.top()]=0;
s.pop();
}
col[x]=x;ins[x]=0;
s.pop();
}
return;
}
void Topsort(){
for(int i=1;i<=n;i++)
if(!in[i])q.push(i);
while(!q.empty()){
int x=q.front();q.pop();
Mx[x]=max(Mx[x],mx[x]);
Mi[x]=min(Mi[x],mi[x]);
ans[x]=max(ans[x],mx[x]-Mi[x]);
ans[x]=max(ans[x],Mx[x]-mi[x]);
for(int i=0;i<T[x].size();i++){
int y=T[x][i].first,w=T[x][i].second;
in[y]--;
Mx[y]=max(Mx[y],max(Mx[x],w));
Mi[y]=min(Mi[y],min(Mi[x],w));
ans[y]=max(ans[y],ans[x]);
ans[y]=max(ans[y],w-Mi[x]);
ans[y]=max(ans[y],Mx[x]-w);
if(!in[y])q.push(y);
}
}
return;
}
int main()
{
scanf("%d%d%d",&n,&m,&t);
for(int i=1;i<=m;i++){
int x,y,w;
scanf("%d%d%d",&x,&y,&w);
G[x].push_back(mp(y,w));
}
tarjan(1);
memset(mi,0x3f,sizeof(mi));
memset(Mi,0x3f,sizeof(Mi));
for(int x=1;x<=n;x++){
for(int i=0;i<G[x].size();i++){
int y=G[x][i].first,w=G[x][i].second;y=col[y];
if(col[x]==y)mx[y]=max(mx[y],w),mi[y]=min(mi[y],w);
else T[col[x]].push_back(mp(y,w)),in[y]++;
}
}
Topsort();
while(t--){
int x;
scanf("%d",&x);
if(x==1||!col[x])puts("-1");
else printf("%d\n",ans[col[x]]);
}
return 0;
}