HihoCoder 1185 : 連通性·三(強連通縮點)
阿新 • • 發佈:2017-11-07
ref name ota while 時間限制 pro int cst str
連通性·三
時間限制:10000ms 單點時限:1000ms 內存限制:256MB描述
暑假到了!!小Hi和小Ho為了體驗生活,來到了住在大草原的約翰家。今天一大早,約翰因為有事要出去,就拜托小Hi和小Ho忙幫放牧。
約翰家一共有N個草場,每個草場有容量為W[i]的牧草,N個草場之間有M條單向的路徑。
小Hi和小Ho需要將牛羊群趕到草場上,當他們吃完一個草場牧草後,繼續前往其他草場。當沒有可以到達的草場或是能夠到達的草場都已經被吃光了之後,小hi和小Ho就把牛羊群趕回家。
一開始小Hi和小Ho在1號草場,在回家之前,牛羊群最多能吃掉多少牧草?
舉個例子:
圖中每個點表示一個草場,上部分數字表示編號,下部分表示草場的牧草數量w。
在1吃完草之後,小Hi和小Ho可以選擇把牛羊群趕到2或者3,假設小Hi和小Ho把牛羊群趕到2:
吃完草場2之後,只能到草場4,當4吃完後沒有可以到達的草場,所以小Hi和小Ho就把牛羊群趕回家。
若選擇從1到3,則可以到達5,6:
選擇5的話,吃完之後只能直接回家。若選擇6,還可以再通過6回到3,再到5。
所以該圖可以選擇的路線有3條:
1->2->4 total: 11 1->3->5 total: 9 1->3->6->3->5: total: 13
所以最多能夠吃到的牧草數量為13。
本題改編自USACO月賽金組
提示:強連通分量
輸入
第1行:2個正整數,N,M。表示點的數量N,邊的數量M。1≤N≤20,000, 1≤M≤100,000
第2行:N個正整數,第i個整數表示第i個牧場的草量w[i]。1≤w[i]≤100,000
第3..M+2行:2個正整數,u,v。表示存在一條從u到v的單向路徑。1≤u,v≤N
輸出
第1行:1個整數,最多能夠吃到的牧草數量。
- 樣例輸入
-
6 6 2 4 3 5 4 4 1 2 2 4 1 3 3 5 3 6 6 3
- 樣例輸出
-
13
#include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #include<vector> using namespace std; #define LL long long const int maxm=200010; int Laxt[maxm],Next[maxm],To[maxm],cnt; int w[maxm],dfn[maxm],low[maxm],times; int q[maxm],head,scc_cnt,scc[maxm],n,instk[maxm]; LL V[maxm],Max; vector<int>G[maxm]; void add(int u,int v) { Next[++cnt]=Laxt[u]; Laxt[u]=cnt; To[cnt]=v; } void rebuild() { for(int i=1;i<=n;i++){ for(int j=Laxt[i];j;j=Next[j]){ if(scc[i]!=scc[To[j]]){ G[scc[i]].push_back(scc[To[j]]); } } } } void dfs(int u) { instk[u]=1; q[++head]=u; dfn[u]=low[u]=++times; for(int i=Laxt[u];i;i=Next[i]){ int v=To[i]; if(!dfn[v]) { dfs(v); low[u]=min(low[u],low[v]); } else if(instk[v])low[u]=min(low[u],dfn[v]); } if(dfn[u]==low[u]){ scc_cnt++; while(true){ int x=q[head--]; scc[x]=scc_cnt; V[scc_cnt]+=w[x]; instk[x]=0; if(x==u) break; } } } void dfs2(int u,LL sum) { sum+=V[u]; Max=max(sum,Max); for(int i=0;i<G[u].size();i++){ dfs2(G[u][i],sum); } } int main() { int m,i,u,v; scanf("%d%d",&n,&m); for(i=1;i<=n;i++) scanf("%d",&w[i]); for(i=1;i<=m;i++){ scanf("%d%d",&u,&v); add(u,v); } dfs(1); rebuild(); dfs2(scc[1],0); printf("%lld\n",Max); return 0; }
HihoCoder 1185 : 連通性·三(強連通縮點)