ATM(BZOJ 1179)
生活随笔
收集整理的這篇文章主要介紹了
ATM(BZOJ 1179)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
測評傳送門
題意:
給你一個有向無環圖,每個點有一個權值,給定起點,和多個終點。
求到達終點的最大權值。
輸入
6 7?
1 2?
2 3?
3 5?
2 4?
4 1?
2 6?
6 5?
10 12 8 16 1 5?
1 4?
4 3 5 6?
輸出
47?
?
思路:
Tarjan 縮點,點權轉邊權,跑SPFA
感謝nan葛格的博客講解
code
#include<stdio.h> #include<stack> #include<queue> #include<algorithm> using namespace std; const int mxn=510000; struct Edge {int to,next; }e[mxn<<1],E[mxn<<1]; int n,m,cnt,idx,tot,st,k,ans; int first[mxn<<1],dfn[mxn],low[mxn],w[mxn],W[mxn],bel[mxn],dis[mxn],head[mxn<<1]; bool ins[mxn],vis[mxn]; stack<int> stk; queue<int> q; void add(int from,int to) {e[++cnt].to=to;e[cnt].next=first[from];first[from]=cnt; }void Tarjan(int x) {dfn[x]=low[x]=++idx;ins[x]=1;stk.push(x);for(int i=first[x];i;i=e[i].next) {int to=e[i].to;if(!dfn[to]) {Tarjan(to);low[x]=min(low[x],low[to]);} else if(ins[to]) low[x]=min(low[x],dfn[to]);}if(low[x]==dfn[x]) {tot++;int top;do {top=stk.top();stk.pop();ins[top]=0;bel[top]=tot;}while(top!=x);} }void rebuild() { for(int x=1;x<=n;++x) {for(int i=first[x];i;i=e[i].next) {int to=e[i].to;if(bel[x]==bel[to]) continue;E[++cnt].to=bel[to];E[cnt].next=head[bel[x]];head[bel[x]]=cnt;}W[bel[x]]+=w[x];} }void spfa() {dis[bel[st]]=W[bel[st]];q.push(bel[st]);while(!q.empty()) {int x=q.front();q.pop();vis[x]=0;for(int i=head[x];i;i=E[i].next) {int to=E[i].to;if(dis[x]+W[to]>dis[to]) {dis[to]=dis[x]+W[to];if(!vis[to]) {vis[to]=1;q.push(to);}}}} }int main() {scanf("%d%d",&n,&m);for(int i=1;i<=m;++i) {int from,to; scanf("%d%d",&from,&to);add(from,to);}for(int i=1;i<=n;++i) {scanf("%d",&w[i]);if(!dfn[i]) Tarjan(i);}cnt=0;rebuild();scanf("%d%d",&st,&k);spfa();for(int i=1;i<=k;++i) {int x;scanf("%d",&x);ans=max(ans,dis[bel[x]]);}printf("%d",ans);return 0; } /* 6 7 1 2 2 3 3 5 2 4 4 1 2 6 6 5 10 12 8 16 1 5 1 4 4 3 5 6 */?
轉載于:https://www.cnblogs.com/qseer/p/9831711.html
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的ATM(BZOJ 1179)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: shell脚本知识点汇总
- 下一篇: .Net NPOI 根据excel模板导