Comet OJ(Contest #14)-飞翔的小鸟【tarjan】
生活随笔
收集整理的這篇文章主要介紹了
Comet OJ(Contest #14)-飞翔的小鸟【tarjan】
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
正題
題目鏈接:https://www.cometoj.com/contest/73/problem/E?problem_id=4124
題目大意
給出nnn個點mmm條邊的一張有向圖,邊有邊權(quán),qqq次詢問從點111走到點xxx的所有路徑(可以重復(fù)經(jīng)過任何點包括點xxx)中極差最大是多少。
1≤n≤2×105,1≤m≤5×1051\leq n\leq 2\times 10^5,1\leq m\leq 5\times 10^51≤n≤2×105,1≤m≤5×105
解題思路
首先肯定要tarjantarjantarjan縮點,然后考慮怎么統(tǒng)計極差。
考慮到極差其實到某個位置的時候就已經(jīng)不會再改變了,而且這個到這個位置的路徑一定是作為最小值或者最大值的。
所以我們可以維護一個路徑上的最大值/最小值和最大極差,然后每次考慮新的轉(zhuǎn)移會不會更新極差就可以了。
時間復(fù)雜度:O(n+m)O(n+m)O(n+m)
CometOJ評測機炸了,代碼沒測就當(dāng)過了吧…
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; }總結(jié)
以上是生活随笔為你收集整理的Comet OJ(Contest #14)-飞翔的小鸟【tarjan】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 3500元笔记本电脑配置单(3500元的
- 下一篇: P3639-[APIO2013]道路费用