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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

P7516 [省选联考 2021 A/B 卷] 图函数

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

解析

純純的人類智慧題。

關鍵性質:vvv 可以在計算 f(u,G)f(u,G)f(u,G) 時產生貢獻,當且僅當 GGGu,vu,vu,v 之間可以通過 [v,n][v,n][v,n] 的點互相到達。
充分性較為顯然,編號更大的點不會比 vvv 先刪去,所以必然在 vvv 時刻依然存在。
必要性證明:假設 vvv 時刻 u→vu\to vuv 的路徑上存在一個 x∈[1,v)x\in [1,v)x[1,v),在 xxx 時刻圖的聯通性不弱于 vvv 時刻,因而必然也有 u→xu\to xux 可達,且由于 x→v,v→ux\to v,v\to uxv,vu 皆可達,也就有 x→ux\to uxu 可達,xxx 應當被刪去,矛盾。

接下來的任務就是如何維護這個東西。

floyd

對于點編號屬于 [v,n][v,n][v,n] 這樣的限制,不難想到 floyd。但是直接跑無法通過 n=1000n=1000n=1000
然后拿大樣例試了試,發現寫成:

for(int k=n;k>=1;k--){for(int i=1;i<=k;i++){for(int j=i;j<=n;j++){k -> update(i,j)}}}

答案依然是對的,并且能跑過1000了。
然后就完事了。

我們當然要想一想為什么這樣是對的。
這么轉移必然出問題的就是兩邊的點編號均大于 kkk 的情況。
如圖中的 p,qp,qp,q
(高度表示點編號的相對大小)

那么我們現在就要證明:

(x,y)(x,y)(x,y) 路徑上沒有經過 [1,min?(x,y))[1,\min(x,y))[1,min(x,y)) 的點,就必然可以正確轉移。

假設枚舉到中轉點 kkk 之前的路徑都符合這個性質。
對于當前枚舉的中轉點 kkk,注意到我們需要求出的合法路徑必然至少有一個端點是小于 kkk 的。
那么就必然能在 kkk 的某一側找到第一個編號小于 kkk 的點 xxxk→xk\to xkx 這段路徑使用 (k,n](k,n](k,n] 的點中轉,不會出現現在 p,qp,qp,q 這樣的窘境,所以 f(k,x)f(k,x)f(k,x) 當前是對的。
那么 xxx 就可以通過 kkk 連接起另一側的 ppp ,得到正確的 f(p,x)f(p,x)f(p,x)
如果 (u,p)(u,p)(u,p) 之間有 k′k'k 這樣的點導致 f(u,p)f(u,p)f(u,p) 不對怎么辦?把(u,p)(u,p)(u,p) 最小的點 k′k'k 當成 ppp 的角色來考慮,剛才的證明就還是對的。

bfs

本題看題解,還有通過 bfs 求對每個 vvv 考慮在每張圖中能對多少 uuu 產生貢獻的方法來做的,每次 bfs 用到一條邊就直接刪去,從而保證復雜度為 O(nm)O(nm)O(nm),也挺妙的。

代碼

#include<bits/stdc++.h> using namespace std; #define ll long long #define ull unsigned long long #define debug(...) fprintf(stderr,__VA_ARGS__) #define ok debug("OK\n") using namespace std;const int N=1050; const int M=2e5+100; const int inf=1e9; const int mod=19921228;inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)) {if(c=='-')f=-1;c=getchar();}while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f; }int n,m; int f[N][N]; ll sum[M];signed main() { #ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout); #endif//memset(f,0x3f,sizeof(f));n=read();m=read();for(int i=1;i<=m;i++){int x=read(),y=read();f[x][y]=i;}for(int i=1;i<=n;i++) f[i][i]=m+1;for(int k=n;k>=1;k--){for(int i=k;i<=n;i++) sum[min(f[i][k],f[k][i])]++;for(int i=1;i<=k;i++){//if(!f[i][k]&&!f[k][i]) continue;for(int j=i;j<=n;j++){f[i][j]=max(f[i][j],min(f[i][k],f[k][j]));f[j][i]=max(f[j][i],min(f[j][k],f[k][i]));}}}for(int i=m;i>=1;i--) sum[i]+=sum[i+1];for(int i=1;i<=m+1;i++) printf("%lld ",sum[i]);return 0; } /* */

總結

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

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