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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

P7516-[省选联考2021A/B卷]图函数【bfs】

發(fā)布時間:2023/12/3 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 P7516-[省选联考2021A/B卷]图函数【bfs】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

正題

題目鏈接:https://www.luogu.com.cn/problem/P7516


題目大意

懶了,直接抄題意了
對于一張 nnn 個點 mmm 條邊的有向圖 GGG(頂點從 1~n1 \sim n1n 編號),定義函數 f(u,G)f(u, G)f(u,G)

  • 初始化返回值 cnt=0cnt = 0cnt=0,圖 G′=GG'= GG=G
  • 111nnn 按順序枚舉頂點 vvv,如果當前的圖 G′;G';G; 中,從 uuuvvv 與從 vvvuuu 的路徑都存在,則將 cnt+1cnt + 1cnt+1,并在圖 G′;G';G; 中刪去頂點 vvv 以及與它相關的邊。
  • 222 步結束后,返回值 cntcntcnt 即為函數值。
  • 現在給定一張有向圖 GGG,請你求出 h(G)=f(1,G)+f(2,G)+?+f(n,G)h(G) = f(1, G) + f(2, G) + \cdots + f(n, G)h(G)=f(1,G)+f(2,G)+?+f(n,G) 的值。

    更進一步地,記刪除(按輸入順序給出的)第 111iii 條邊后的圖為 GiG_iGi?1≤i≤m1 \le i \le m1im),請你求出所有 h(Gi)h(G_i)h(Gi?) 的值。

    1≤n≤103,1≤m≤2×1051\leq n\leq 10^3,1\leq m\leq 2\times 10^51n103,1m2×105


    解題思路

    但凡一個不按慣性思維思考的方法都可以做出這道題

    這個刪邊就很意義不明,反過來直接改成加邊就簡單很多。

    然后還有一個問題就是是否刪點的判斷也是沒有必要的:

    假設對于起點uuu能走到vvvvvv不能走到uuu,那么顯然并不存在一個節(jié)點xxx使得uuu能走到xxxxxx能走到uuu并且vvv是這些路徑的必經點,因為那么vvv肯定在這個環(huán)上,那么vvv顯然能走到uuu

    所以現在f(u,G)f(u,G)f(u,G)能否統(tǒng)計vvv就變?yōu)榱伺袛嗍欠翊嬖谝粋€u→v→uu\rightarrow v\rightarrow uuvu的環(huán)使得路徑上的所有點編號不小于min(u,v)min(u,v)min(u,v)

    那么不妨考慮一下兩個點對(u,v)(u,v)(u,v)之間不斷加邊之后第一次產生貢獻的時間,每條邊的權值設為加入的時間,這個時間就是u→v→uu\rightarrow v\rightarrow uuvu的一條不經過編號小于min(u,v)min(u,v)min(u,v)點的情況下最大權值最小的路徑。

    這樣Flody就有O(n3)O(n^3)O(n3)的算法了。

    然后我們想了很久感覺最短路行不通,那么此時就需要摒棄慣性思維的想法了,我們考慮另一個更暴力的做法,我們每次加邊然后暴力判斷每個點之間的聯通,發(fā)現這樣的時間復雜度是O(nm2)O(nm^2)O(nm2)的。

    然后依舊的我們考慮另一種可能,我們最外層不枚舉加邊,而是枚舉需要統(tǒng)計答案的起點uuu,然后每次加一條邊(x,y)(x,y)(x,y),如果uuu能走到xxx且不能走到yyy那么此時uuu能走到yyy了,從yyy開始bfsbfsbfs所有其他沒有走過的節(jié)點,需要注意的是走過的邊兩邊都是遍歷過的所以可以直接刪除。

    這樣的時間復雜度就是O(n(n+m))O(n(n+m))O(n(n+m)),可以通過本題。

    需要卡常


    code

    #include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<queue> using namespace std; const int N=1e3+10,M=2e5+10; struct node{int to,next; }a[M]; int n,m,f[N][N],g[N][N]; int ex[M],ey[M],ans[M]; vector<int> G[N],D[N];queue<int> q; void bfs(int x,int s,int w){q.push(x);while(!q.empty()){int x=q.front();q.pop();f[s][x]=w;for(int i=0;i<G[x].size();i++)if(!f[s][G[x][i]])q.push(G[x][i]);G[x].clear();}return; } void bgs(int x,int s,int w){q.push(x);while(!q.empty()){int x=q.front();q.pop();g[s][x]=w;for(int i=0;i<D[x].size();i++)if(!g[s][D[x][i]])q.push(D[x][i]);D[x].clear();}return; } int main() {scanf("%d%d",&n,&m);m++;for(int i=2;i<=m;i++)scanf("%d%d",&ex[i],&ey[i]);reverse(ex+2,ex+1+m);reverse(ey+2,ey+1+m);for(int x=1;x<=n;x++){for(int i=1;i<=n;i++)G[i].clear();for(int i=1;i<=n;i++)D[i].clear();f[x][x]=g[x][x]=1;for(int i=2;i<=m;i++){if(ex[i]<x||ey[i]<x)continue;if(f[x][ex[i]]&&!f[x][ey[i]])bfs(ey[i],x,i);else if(!f[x][ex[i]]&&!f[x][ey[i]])G[ex[i]].push_back(ey[i]);if(g[x][ey[i]]&&!g[x][ex[i]])bgs(ex[i],x,i);else if(!g[x][ey[i]]&&!g[x][ex[i]])D[ey[i]].push_back(ex[i]);}}for(int i=1;i<=n;i++)for(int j=i;j<=n;j++)if(f[i][j]&&g[i][j])ans[max(f[i][j],g[i][j])]++;for(int i=1;i<=m;i++)ans[i]+=ans[i-1];reverse(ans+1,ans+1+m);for(int i=1;i<=m;i++)printf("%d ",ans[i]);return 0; }

    總結

    以上是生活随笔為你收集整理的P7516-[省选联考2021A/B卷]图函数【bfs】的全部內容,希望文章能夠幫你解決所遇到的問題。

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