zoukankan      html  css  js  c++  java
  • LOJ10096掠夺计划

    题目传送门:https://loj.ac/problem/10096

    -------------------------------------------------------------------------------------------------------

    强联通分量内的ATM只要有一个可以抢到就都可以抢到的,所以要缩点。

    当然,要统计整个分量内可以抢到的钱的和。

    分量内只要有一个路口有酒吧,那么这个分量就可以作为结束点进行庆祝,所以要统计每个分量内是否有酒吧。

    然后在缩点后的有向无环图上进行拓扑排序,然后进行DP,求出到每个分量可以抢到的最大钱数。

    最后把所有抢到钱的分量中,求出有酒吧且最大的就是答案。

    -------------------------------------------------------------------------------------------------------

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=5e5+10;
     4 const int maxm=5e5+10;
     5 int n,m;
     6 struct edge
     7 {
     8     int u,v,nxt;
     9 }e[maxm],ee[maxm];
    10 int head[maxn],js,headd[maxn],jss;
    11 void addage(edge e[],int head[],int &js,int u,int v)
    12 {
    13     e[++js].u=u;e[js].v=v;
    14     e[js].nxt=head[u];head[u]=js;
    15 }
    16 int dfn[maxn],low[maxn],st[maxn],top,cnt,lt[maxn],lts;
    17 void tarjan(int u)
    18 {
    19     dfn[u]=low[u]=++cnt;
    20     st[++top]=u;
    21     for(int i=head[u];i;i=e[i].nxt)
    22     {
    23         int v=e[i].v;
    24         if(!dfn[v])
    25         {
    26             tarjan(v);
    27             low[u]=min(low[u],low[v]);
    28         }
    29         else if(!lt[v])
    30             low[u]=min(low[u],dfn[v]);
    31     }
    32     if(dfn[u]==low[u])
    33     {
    34         lt[u]=++lts;
    35         while(st[top]!=u)lt[st[top--]]=lts;
    36         --top;
    37     }
    38 }
    39 int money[maxn],moneys[maxn],s,p;
    40 bool isp[maxn],isps[maxn];
    41 int f[maxn];
    42 bool inq[maxn];
    43 queue<int>q;
    44 void dfs(int x)
    45 {
    46     q.push(x);
    47     while(!q.empty())
    48     {
    49         int u=q.front();q.pop();inq[u]=0;
    50         for(int i=headd[u];i;i=ee[i].nxt)
    51         {
    52             int v=ee[i].v;
    53             if(f[u]+moneys[v]>f[v])
    54             {
    55                 f[v]=f[u]+moneys[v];
    56                 if(!inq[v])
    57                 {
    58                     q.push(v);
    59                     inq[v]=1;
    60                 }
    61             }
    62         }
    63     }
    64 }
    65 int main()
    66 {
    67     scanf("%d%d",&n,&m);
    68     for(int u,v,i=0;i<m;++i)
    69     {
    70         scanf("%d%d",&u,&v);
    71         addage(e,head,js,u,v);
    72     }
    73     for(int i=1;i<=n;++i)scanf("%d",money+i);
    74     scanf("%d%d",&s,&p);
    75     for(int x,i=0;i<p;++i)
    76     {
    77         scanf("%d",&x);
    78         isp[x]=1;
    79     }
    80     for(int i=1;i<=n;++i)
    81         if(!dfn[i])tarjan(i);
    82     for(int i=1;i<=n;++i)
    83     {
    84         moneys[lt[i]]+=money[i];
    85         if(isp[i])isps[lt[i]]=1;
    86     }
    87     for(int u=1;u<=n;++u)
    88         for(int i=head[u];i;i=e[i].nxt)
    89         {
    90             int v=e[i].v;
    91             if(lt[u]!=lt[v])addage(ee,headd,jss,lt[u],lt[v]);
    92         }
    93     f[lt[s]]=moneys[lt[s]];
    94     dfs(lt[s]);
    95     int ans=0;
    96     for(int i=1;i<=lts;++i)if(isps[i])ans=max(ans,f[i]);
    97     cout<<ans;
    98     return 0; 
    99 }
    View Code
  • 相关阅读:
    找到搜索的北了
    zoj2741Offside
    hdu: 1426 ( Sudoku Killer )
    悲剧的矩阵乘法
    UVa729 The Hamming Distance Problem
    hdu 1584 蜘蛛牌
    zoj2972Hurdles of 110m
    hdu 1372 ( Knight Moves ) BFS
    UVa193Graph Coloring
    zjut1624序列问题
  • 原文地址:https://www.cnblogs.com/gryzy/p/10765152.html
Copyright © 2011-2022 走看看