zoukankan      html  css  js  c++  java
  • APIO2009 洛谷P3678 劫掠计划

    题目传送门:https://www.luogu.org/problemnew/show/P3627

    题解:tarjan强连通分量缩点+bfsspfa

    代码如下:

     1 #include<cstdio>
     2 #include<iostream>
     3 #define MN 1000010
     4 using namespace std;
     5 int n,m,w[MN],bar[MN],S,P,ans,hd[MN],cnt,sz[MN],CN,dis[MN],s[MN];
     6 int dye[MN],q[MN],top,dfn[MN],low[MN],dfs_ct,re_ct,re_hd[MN];
     7 bool vis[MN];
     8 struct node{int to,nex,d;}e[MN],re_e[MN];
     9 void add(int x,int y){e[++cnt].to=y;e[cnt].nex=hd[x];hd[x]=cnt;}
    10 void tarjan(int x){
    11     vis[q[++top]=x]=true;
    12     dfn[x]=low[x]=++dfs_ct;
    13     for(int i=hd[x];i;i=e[i].nex){
    14         if(!dfn[e[i].to]){
    15             tarjan(e[i].to);
    16             low[x]=min(low[x],low[e[i].to]);
    17         }
    18         else if(vis[e[i].to])
    19             low[x]=min(low[x],dfn[e[i].to]);
    20     }
    21     if(dfn[x]==low[x]){
    22         vis[x]=false;
    23         sz[dye[x]=++CN]+=w[x];
    24         while(x!=q[top]){
    25             sz[dye[q[top]]=CN]+=w[q[top]];
    26             vis[q[top--]]=false;
    27         }
    28         --top;
    29     }
    30 }
    31 void rebuild(){
    32     for(int i=1;i<=n;++i)
    33         for(int j=hd[i];j;j=e[j].nex)
    34             if(dye[i]!=dye[e[j].to]&&dye[i]&&dye[e[j].to]){
    35                 re_e[++re_ct].to=dye[e[j].to];
    36                 re_e[re_ct].d=sz[dye[e[j].to]];
    37                 re_e[re_ct].nex=re_hd[dye[i]];
    38                 re_hd[dye[i]]=re_ct;
    39             }
    40 }
    41 bool spfa(int u){
    42     int head=1,tail=1; s[1]=u;
    43     while(head<=tail){
    44         u=s[head++];
    45         for(int i=re_hd[u];i;i=re_e[i].nex){
    46             int v=re_e[i].to;
    47             if(re_e[i].d+dis[u]>dis[v]){
    48                 dis[v]=re_e[i].d+dis[u];
    49                 s[++tail]=v;
    50             }
    51         }
    52     }
    53 }
    54 int main()
    55 {
    56     scanf("%d%d",&n,&m);
    57     for(int i=1;i<=m;i++){
    58         int x,y; scanf("%d%d",&x,&y);
    59         add(x,y);
    60     }
    61     for(int i=1;i<=n;i++) scanf("%d",&w[i]);
    62     scanf("%d%d",&S,&P);
    63     for(int i=1;i<=P;i++){
    64         int x; scanf("%d",&x);
    65         bar[x]=true;
    66     }
    67     for(int i=1;i<=n;i++)if(!dye[i]) tarjan(i);
    68     rebuild();
    69     dis[dye[S]]=sz[dye[S]];
    70     spfa(dye[S]);
    71     for(int i=1;i<=n;i++)
    72         if(bar[i])if(dis[dye[i]]>ans) ans=dis[dye[i]];
    73     printf("%d",ans);
    74     return 0;
    75 }
  • 相关阅读:
    cf605 div3
    how to find Longest Increasing Subsequence Size
    luogu1641 [SDOI2010]生成字符串
    luogu1441 砝码称重
    luogu4218 [JSOI2008] 最小生成树计数
    luogu1514 引水入城
    luogu1312 Mayan游戏 剪枝
    luogu1081 开车旅行 树上倍增
    luogu1052 过河
    luogu1026 统计单词个数
  • 原文地址:https://www.cnblogs.com/Beginner-/p/8795716.html
Copyright © 2011-2022 走看看