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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

洛谷P3119

發布時間:2023/12/10 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 洛谷P3119 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

省選難度啊啊啊
經評論區的朋友提醒,代碼已訂正
先說一下該題思路:
首先,這題并非是求最短路,而是求最長路(最長路常用算法一般是拓撲排序,而我這個蒟蒻還沒有學會QAQ)
但是這一題既然標簽是連通圖,那么肯定要用tarjan,考慮到縮點之后每個縮點都具有一定數量的點數,然后如果我們進入了這個縮點,那么我們可以從進入該縮點的點起,然后將整個縮點中的點全部遍歷一遍,所以我們可以將縮點中的點數作為邊的權值(既然有權值那么我們就可以跑spfa),進行縮點之后就可以重新建圖,所以在這里我們有三個first,nxt,v,然后我們要跑兩邊spfa,所以我們要有兩個dis數組來保存正向和逆向的距離,然后只需要枚舉每個點,同時用最大值來更新ans

#include<iostream> #include<cstdio> #include<cstring> #include<stack> #include<queue> using namespace std; const int maxn=100003; stack<int> s; queue<int> q; int tot,tot1,tot2; int v[maxn],v1[maxn],v2[maxn]; int nxt[maxn],nxt1[maxn],nxt2[maxn]; int first[maxn],f1[maxn],f2[maxn]; int ins[maxn],dfn[maxn],low[maxn]; int c[maxn],cnt[maxn],use[maxn]; int dis1[maxn],dis2[maxn]; int timing,col; void add(int x,int y) {v[tot]=y;nxt[tot]=first[x];first[x]=tot++; } void add1(int x,int y) {v1[tot1]=y;nxt1[tot1]=f1[x];f1[x]=tot1++; } void add2(int x,int y) {v2[tot2]=y;nxt2[tot2]=f2[x];f2[x]=tot2++; } void tarjan(int x) {ins[x]=1;s.push(x);dfn[x]=low[x]=++timing;for(int to=first[x];to!=-1;to=nxt[to]){if(!dfn[v[to]]){tarjan(v[to]);low[x]=min(low[x],low[v[to]]);}else if(ins[v[to]])low[x]=min(low[x],low[v[to]]);}if(dfn[x]==low[x]){col++;int k;do{k=s.top();ins[k]=0;c[k]=col;cnt[col]++;s.pop();} while (k!=x);} } void spfa1(int x) {dis1[x]=cnt[x];q.push(x);while(!q.empty()){int k=q.front();q.pop();for(int to=f1[k];to!=-1;to=nxt1[to]){if(dis1[v1[to]]<dis1[k]+cnt[v1[to]])dis1[v1[to]]=dis1[k]+cnt[v1[to]];if(!ins[v1[to]]){q.push(v1[to]);ins[v1[to]]=1;}}ins[k]=0;} } void spfa2(int x) {dis2[x]=cnt[x];q.push(x);while(!q.empty()){int k=q.front();q.pop();for(int to=f2[k];to!=-1;to=nxt2[to]){if(dis2[v2[to]]<dis2[k]+cnt[v2[to]])dis2[v2[to]]=dis2[k]+cnt[v2[to]];if(!ins[v2[to]]){q.push(v2[to]);ins[v2[to]]=1;}}ins[k]=0;} } int main() {int n,m,a,b,start;cin>>n>>m;memset(first,-1,sizeof(first));memset(f1,-1,sizeof(f1));memset(f2,-1,sizeof(f2));for(int k=0;k<m;k++){scanf("%d%d",&a,&b);add(a,b);}for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i);start=c[1];for(int i=1;i<=n;i++)for(int to=first[i];to!=-1;to=nxt[to])if(c[i]!=c[v[to]]){add1(c[i],c[v[to]]);add2(c[v[to]],c[i]);}spfa1(start);spfa2(start);int ans=cnt[start];for(int i=1;i<=n;i++)if(!use[c[i]] && dis1[c[i]]){use[c[i]]=1;for(int to=f2[c[i]];to!=-1;to=nxt2[to]){if(!dis2[v2[to]])continue;ans=max(dis1[c[i]]+dis2[v2[to]]-cnt[start],ans);}}cout<<ans;return 0; }

好像說了這么久,應該只有我自己一個人懂吧233333

另一個神犇的分層法暫時還沒懂23333

總結

以上是生活随笔為你收集整理的洛谷P3119的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。