C++ P2883 [USACO07MAR]牛交通Cow Traffic
阿新 • • 發佈:2018-11-19
題目描述
隨著牛的數量增加,農場的道路的擁擠現象十分嚴重,特別是在每天晚上的擠奶時間。為了解決這個問題,FJ決定研究這個問題,以能找到導致擁堵現象的瓶頸所在。
牧場共有M條單向道路,每條道路連線著兩個不同的交叉路口,為了方便研究,FJ將這些交叉路口編號為1..N,而牛圈位於交叉路口N。任意一條單向道路的方向一定是是從編號低的路口到編號高的路口,因此農場中不會有環型路徑。同時,可能存在某兩個交叉路口不止一條單向道路徑連線的情況。
在擠奶時間到來的時候,奶牛們開始從各自的放牧地點回到牛圈。放牧地點是指那些沒有道路連線進來的路口(入度為0的頂點)。
現在請你幫助fj通過計算從放牧點到達牛圈的路徑數目來找到最繁忙的道路(答案保證是不超過32位整數)。
輸入輸出格式
輸入格式:
第一行: N 和 M.
第2到M+1行: 兩個相連的點
輸出格式:
第一行:最繁忙的一條道路被經過的次數數量
題目連結:https://www.luogu.org/problemnew/show/P2883
個人思路:
- 從題意中,我們可以觀察到,如果將每一個路口抽象為一個點,那麼該圖為DAG.
- 由於要處理的最繁忙的道路的被經過的數量與邊有關,我們可以考慮到拓撲排序。
- 通過在DAG上的總結,再結合我們在小學學過的乘法原理,我們可以考慮到一個規律:在一條邊M(u->v)上,通過M的方法數量為從源點到達u的方式數量*從終點到達v的方式數量
- 之後,進行兩次拓撲排序即可。(一次正向,一次反向.)
#include<cstdio> #include<iostream> #include<queue> using namespace std; int n,cnt=0,ans=0,head[5005],rd[5005],dp[5005]; struct Edge{ int v,w,nxt; }e[50005],e2[50005]; void addEdge(int u,int v,int w){ e[++cnt].v=v; e[cnt].w=w; e[cnt].nxt=head[u]; head[u]=cnt; } void topoSort(){ queue<int> q; for(int i=1;i<=n;i++){ if(rd[i]==0){ q.push(i); dp[i]=1; } } while(!q.empty()){ int nowValue=q.front();q.pop(); for(int i=head[nowValue];i;i=e[i].nxt){ rd[e[i].v]--; dp[e[i].v]+=dp[nowValue]; //cout<<"dp["<<e[i].v<<"]+=dp["<<nowValue<<"]"<<endl; ans=max(ans,dp[e[i].v]); if(rd[e[i].v]==0){ q.push(e[i].v); } } } } int cnt2=0,ans2=0,head2[5005],rd2[5005],dp2[5005]; void addEdge2(int u,int v,int w){ e2[++cnt2].v=v; e2[cnt2].w=w; e2[cnt2].nxt=head2[u]; head2[u]=cnt2; } void topoSort2(){ queue<int> q; for(int i=1;i<=n;i++){ if(rd2[i]==0){ q.push(i); dp2[i]=1; } } while(!q.empty()){ int nowValue=q.front();q.pop(); for(int i=head2[nowValue];i;i=e2[i].nxt){ rd2[e2[i].v]--; dp2[e2[i].v]+=dp2[nowValue]; //cout<<"dp2["<<e2[i].v<<"]+=dp2["<<nowValue<<"]"<<endl; ans2=max(ans2,dp2[e2[i].v]); if(rd2[e2[i].v]==0){ q.push(e2[i].v); } } } } int trueAns=0; void work(){ queue<int> q; for(int i=1;i<=n;i++){ if(rd[i]==0){ q.push(i); } } while(!q.empty()){ int nowValue=q.front();q.pop(); for(int i=head[nowValue];i;i=e[i].nxt){ rd[e[i].v]--; trueAns=max(trueAns,dp[nowValue]*dp2[e[i].v]); if(rd[e[i].v]==0){ q.push(e[i].v); } } } } int main(){ //freopen("in.in","r",stdin); int m; scanf("%d%d",&n,&m); for(int i=1;i<=m;i++){ int ta,tb; scanf("%d%d",&ta,&tb); addEdge(ta,tb,1); addEdge2(tb,ta,1); rd[tb]++; rd2[ta]++; } topoSort(); topoSort2(); work(); printf("%d\n",trueAns); //printf("%d\n",ans2); return 0; }