• bzoj1179: [Apio2009]Atm


    很久没更博客了qwq

    https://www.lydsy.com/JudgeOnline/problem.php?id=1179

    似乎不是很难,点可以重复走,但只算一次,这么办?考虑把点缩起来,显然这样就可以解决了。

    之后跑跑spfa就行了

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <cstring>
     4 using namespace std;
     5 const int N=500000+5;
     6 int v[N],nxt[N],first[N],cnt;
     7 int bl[N],b[N],w[N];
     8 int low[N],dfn[N],tim;
     9 int st[N],top,sz;
    10 int bar[N],s,n,m,p;
    11 int aa[N],bb[N];
    12 bool vis[N];
    13 
    14 void read(int &x){
    15     x=0;int f=1;char c=getchar();
    16     while(c<'0'||c>'9'){if(c=='-')f=-f;c=getchar();}
    17     while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c-'0');c=getchar();}
    18     x*=f;
    19 }
    20 
    21 void add(int a,int b){
    22     v[++cnt]=b;
    23     nxt[cnt]=first[a];
    24     first[a]=cnt;
    25 }
    26 
    27 void tarjan(int x){
    28     dfn[x]=low[x]=++tim;
    29     st[++top]=x;
    30     vis[x]=1;
    31     for(int i=first[x];i;i=nxt[i]){
    32         if(!dfn[v[i]]){
    33             tarjan(v[i]);
    34             low[x]=min(low[x],low[v[i]]);
    35         }
    36         else if(vis[v[i]]) low[x]=min(low[x],dfn[v[i]]);
    37     }
    38     if(low[x]==dfn[x]){
    39         bl[x]=++sz;
    40         b[sz]=w[x];
    41         vis[x]=0;
    42         while(st[top]!=x){
    43             vis[st[top]]=0;
    44             b[sz]+=w[st[top]];
    45             bl[st[top--]]=sz;
    46         }
    47         --top;
    48     }
    49 }
    50 
    51 void rebuild(){
    52     memset(v,0,sizeof(v));
    53     memset(nxt,0,sizeof(nxt));
    54     memset(first,0,sizeof(first));
    55     cnt=0;
    56     for(int i=1;i<=m;i++) if(bl[aa[i]]!=bl[bb[i]]) add(bl[aa[i]],bl[bb[i]]);
    57 }
    58 
    59 int dis[N],q[N*10];
    60 int inq[N];
    61 void spfa(int s){
    62     for(int i=1;i<=sz;i++) dis[i]=b[i];
    63     inq[s]=1;q[1]=s;
    64     int head=1,tail=2;
    65     while(head!=tail){
    66         int x=q[head++];inq[x]=0;
    67         if(head==N*10) head=1;
    68         for(int i=first[x];i;i=nxt[i])
    69             if(dis[x]+b[v[i]]>dis[v[i]]){
    70                 dis[v[i]]=dis[x]+b[v[i]];
    71                 if(!inq[v[i]]){
    72                     q[tail++]=v[i];inq[v[i]]=1;
    73                     if(tail==N*10) tail=1;
    74                 }
    75             }
    76     }
    77 }
    78 
    79 int main(){
    80     read(n);read(m);
    81     for(int i=1;i<=m;i++){
    82         read(aa[i]);read(bb[i]);
    83         add(aa[i],bb[i]);
    84     }
    85     for(int i=1;i<=n;i++) read(w[i]);
    86     read(s);read(p);
    87     for(int i=1;i<=p;i++) read(bar[i]);
    88     for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i);
    89     rebuild();spfa(bl[s]);
    90     int ans=0;
    91     for(int i=1;i<=p;i++) ans=max(ans,dis[bl[bar[i]]]);
    92     printf("%d",ans);
    93     return 0;
    94 }
    Code
  • 相关阅读:
    第二十四讲 ASP.NET中开发复合控件
    第二十六讲 使用ASP.NET实现网络通讯
    第二十五讲 ASP.NET中的XML
    【经验】android webview 后退键导致表单再次提交
    【笔记】java 泛型
    【笔记】Collection
    【算法】Tween算法
    【JavaSript】发现一个漏洞
    【研究】加载图片时,同一url,多次request
    【笔记】多态之Override
  • 原文地址:https://www.cnblogs.com/lyf2/p/9093196.html
Copyright © 2020-2023  润新知