• 缩点×2


    感觉已经掌握了tarjan的真正思想。。

     1 #include <cstdio>
     2 using namespace std;
     3 
     4 const int maxn=1e4+5, maxm=1e5+5;
     5 
     6 inline int max(int a, int b) { return a<b?b:a; }
     7 inline int min(int a, int b) { return a<b?a:b; }
     8 
     9 class Graph{
    10 public:
    11     struct Edge{
    12         Graph *belong;
    13         int to, next;
    14         Edge operator ++(){ *this=belong->edge[next]; return *this; }
    15         int operator *(){ return to; }
    16     };
    17     void addedge(int a, int b){
    18         Edge &e=edge[++cntedge];
    19         e.to=b, e.next=fir[a];
    20         fir[a]=cntedge, e.belong=this;
    21     }
    22     Edge gete(int x) { return edge[fir[x]]; }
    23     Edge edge[maxm];
    24 private:
    25     int cntedge, fir[maxn];
    26 };
    27 
    28 int n, m, tail, time, cntscc, ans;
    29 int v[maxn], dfn[maxn], low[maxn];
    30 int stack[maxn], instack[maxn];
    31 int belong[maxn], in[maxn], v_scc[maxn], dp[maxn];
    32 Graph g, g_scc;
    33 
    34 void tarjan(int now){
    35     dfn[now]=low[now]=++time;
    36     stack[++tail]=now, instack[now]=1;
    37     int nowson;
    38     for (Graph::Edge e=g.gete(now); *e; ++e){
    39         nowson=*e;
    40         //写在前面比较好,尽管无伤大雅
    41         if (instack[nowson])
    42             low[now]=min(low[now], dfn[nowson]);
    43         if (!dfn[nowson]){
    44             tarjan(nowson);
    45             low[now]=min(low[now], low[nowson]);
    46         }
    47     }
    48     if (dfn[now]==low[now]){
    49         ++cntscc;
    50         for (; low[stack[tail]]!=dfn[stack[tail]]; --tail){
    51             instack[stack[tail]]=0; //这里忘记了!!
    52             belong[stack[tail]]=cntscc;
    53             v_scc[cntscc]+=v[stack[tail]];
    54         }
    55         instack[stack[tail]]=0;
    56         belong[stack[tail]]=cntscc;
    57         v_scc[cntscc]+=v[stack[tail]];
    58         --tail;
    59     }
    60 }
    61 
    62 void dfs(int now, int par){
    63     int nowson;
    64     for (Graph::Edge e=g_scc.gete(now); *e; ++e){
    65         nowson=*e;
    66         if (nowson==par) continue;
    67         if (!dp[nowson]) dfs(nowson, now);
    68         dp[now]=max(dp[now], dp[nowson]);
    69     }
    70     dp[now]+=v_scc[now];
    71     ans=max(ans, dp[now]);
    72 }
    73 
    74 int main(){
    75     scanf("%d%d", &n, &m);
    76     for (int i=1; i<=n; ++i) scanf("%d", &v[i]);
    77     int x, y;
    78     for (int i=0; i<m; ++i){ scanf("%d%d", &x, &y); g.addedge(x, y); }
    79     for (int i=1; i<=n; ++i)
    80         if (!dfn[i]) tarjan(i);
    81     for (int i=1; i<=n; ++i)
    82         for (Graph::Edge e=g.gete(i); *e; ++e){
    83             if (belong[i]!=belong[*e]){
    84                 g_scc.addedge(belong[i], belong[*e]);
    85                 ++in[belong[*e]];
    86             }
    87         }
    88     for (int i=1; i<=cntscc; ++i)
    89         if (!in[i]) dfs(i, 0);
    90     printf("%d
    ", ans);
    91 }
  • 相关阅读:
    SkylineGlobe 如何实现绘制圆形Polygon和对图层的圆形范围选择查询
    如何修改Oracle服务IP地址
    TerraGate软件安装后,不能启动的解决办法
    SkylineGlobe SFS发布的WFS和WMS服务测试
    SkylineGlobe 如何实现二次开发加载KML文件
    如何屏蔽SkylineGlobe提供的三维地图控件上的快捷键
    SkylineGlobe 如何实现FlyTo定位到目标点之后触发的事件函数
    转子百度知道:LTE上行采用DC子载波,而下行置零,为什么?
    转载:LTE小区搜索过程
    dB dBc dBi dBd dBm dBW 定义
  • 原文地址:https://www.cnblogs.com/MyNameIsPc/p/7554046.html
Copyright © 2020-2023  润新知