日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Comet OJ(Contest #14)-飞翔的小鸟【tarjan】

發(fā)布時間:2023/12/3 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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^51n2×105,1m5×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)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。