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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

第十二届湖南省赛 (B - 有向无环图 )(拓扑排序+思维)好题

發布時間:2023/11/30 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 第十二届湖南省赛 (B - 有向无环图 )(拓扑排序+思维)好题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Bobo 有一個 n 個點,m 條邊的有向無環圖(即對于任意點 v,不存在從點 v 開始、點 v 結束的路徑)。 為了方便,點用 1,2,…,n 編號。 設 count(x,y) 表示點 x 到點 y 不同的路徑數量(規定 count(x,x)=0),Bobo 想知道 除以 (10?9+7) 的余數。 其中,a?i,b?j?是給定的數列。

Input

輸入包含不超過 15 組數據。 每組數據的第一行包含兩個整數 n,m (1≤n,m≤10?5). 接下來 n 行的第 i 行包含兩個整數 a?i,b?i?(0≤a?i,b?i≤10?9). 最后 m 行的第 i 行包含兩個整數 u?i,v?i,代表一條從點 u?i?到 v?i?的邊 (1≤u?i,vi≤n)。

Output對于每組數據,輸出一個整數表示要求的值。Sample Input

3 3 1 1 1 1 1 1 1 2 1 3 2 3 2 2 1 0 0 2 1 2 1 2 2 1 500000000 0 0 500000000 1 2

Sample Output

4 4 250000014

Hint

?

?

思路:

由有向圖拓撲序的性質可以知道,拓撲序在后的節點是沒有指向拓撲序在前的節點。

那么我們在對整個圖進行拓撲的時候,把起始點 x 的a[x] 值 附加到 這個邊的終點 y 的a[y] 值上。

并且對于每一個邊,我們維護一個 long long 類型的 答案 ans,ans+= a[x]*b[y]? (? 邊 是 x ~> y )

那么這里就介紹剛剛我們為什么要附加數值a[x] 到a[y]上。

如果由三個點? x y z ,由如下的連接關系 x ~> y ~> z 那么x到y的邊我們會算一次對答案的貢獻值,y到z的邊我們也會算一次。

還有一個x到z的邊,我們仍然需要算。因為x可以到達z,那么如果我們在拓撲的時候把a[y]加上a[x] 時, 我們在算 b到z 的邊的時候就順便的加上了a到z的邊。

因為x 的拓撲優先級比y高,并且x可以到達y,那么x就可以到達y能到達的所有邊,那么就解釋了這樣做的原因。

這樣做的時間復雜度就會轉化為 O ( N )?

主要是理解后就很好寫代碼,可以自己動手畫圖理解一下上面 講的內容。

?

實現細節見ac代碼:

#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <stack> #include <map> #include <set> #include <vector> #include <iomanip> #define ALL(x) (x).begin(), (x).end() #define rt return #define dll(x) scanf("%I64d",&x) #define xll(x) printf("%I64d\n",x) #define sz(a) int(a.size()) #define all(a) a.begin(), a.end() #define rep(i,x,n) for(int i=x;i<n;i++) #define repd(i,x,n) for(int i=x;i<=n;i++) #define pii pair<int,int> #define pll pair<long long ,long long> #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) #define MS0(X) memset((X), 0, sizeof((X))) #define MSC0(X) memset((X), '\0', sizeof((X))) #define pb push_back #define mp make_pair #define fi first #define se second #define eps 1e-6 #define gg(x) getInt(&x) #define db(x) cout<<"== [ "<<x<<" ] =="<<endl; using namespace std; typedef long long ll; ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} ll lcm(ll a,ll b){return a/gcd(a,b)*b;} ll powmod(ll a,ll b,ll MOD){ll ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;} inline void getInt(int* p); const int maxn=100010; const int inf=0x3f3f3f3f; /*** TEMPLATE CODE * * STARTS HERE ***/ std::vector<int> son[maxn]; const ll mod=1e9+7ll; ll ans=0ll; ll a[maxn]; ll b[maxn]; ll num[maxn]; int du[maxn]; int main() {// freopen("D:\\common_text\\code_stream\\in.txt","r",stdin);//freopen("D:\\common_text\\code_stream\\out.txt","w",stdout); gbtb;int n,m;while(cin>>n>>m){repd(i,1,n){son[i].clear();}MS0(du);MS0(num);repd(i,1,n){cin>>a[i]>>b[i];}int x,y;repd(i,1,m){cin>>x>>y;son[x].push_back(y);du[y]++;}queue<int> q;repd(i,1,n){if(!du[i]){q.push(i);}}ans=0ll;while(q.size()){int temp=q.front();q.pop();for(auto x:son[temp]){ans=(ans+(a[temp]*b[x])%mod+mod)%mod;a[x]+=a[temp];a[x]=(a[x]+mod)%mod;du[x]--;if(!du[x]){q.push(x);}}}cout<<ans<<endl;}return 0; }inline void getInt(int* p) {char ch;do {ch = getchar();} while (ch == ' ' || ch == '\n');if (ch == '-') {*p = -(getchar() - '0');while ((ch = getchar()) >= '0' && ch <= '9') {*p = *p * 10 - ch + '0';}}else {*p = ch - '0';while ((ch = getchar()) >= '0' && ch <= '9') {*p = *p * 10 + ch - '0';}} }

?

轉載于:https://www.cnblogs.com/qieqiemin/p/10679978.html

總結

以上是生活随笔為你收集整理的第十二届湖南省赛 (B - 有向无环图 )(拓扑排序+思维)好题的全部內容,希望文章能夠幫你解決所遇到的問題。

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