• 洛谷 P3627 [APIO2009]抢掠计划


    这题一看就是缩点,但是缩完点怎么办呢?首先我们把所有的包含酒吧的缩点找出来,打上标记,然后建立一张新图,

    每个缩点上的点权就是他所包含的所有点的点权和。但是建图的时候要注意,每一对缩点之间可能有多条边,所以我们可以先把重边去除一下,在建立新图,具体操作如下:

     1 for(int i=1;i<=n;i++)
     2     {
     3         if(vis[i]==0) continue;
     4         for(int j=last[i];j;j=g[j].next)
     5         {
     6             int v=g[j].to;
     7             if(g[i].co!=g[v].co&&vis[v]==1)
     8             {
     9                 e[++cnt].a=g[i].co;
    10                 e[cnt].b=g[v].co;
    11             }
    12         }
    13     }
    14     sort(e+1,e+cnt+1,cmp);
    15     for(int i=1;i<=cnt;i++)
    16     {
    17         if(e[i].a!=e[i-1].a||e[i].b!=e[i-1].b)
    18         {
    19             add1(e[i].a,e[i].b);
    20         }                
    21     }
    View Code

    具体思路就是先枚举所有点和所有边,如果两个点不属于同一个强联通分量,那么就用e来把边存一下,然后对e进行排序

    ,去重,再建图。

    建完图之后就好办了,可以跑spfa单源最长路,也可以dp,因为最后一定会终止在酒吧,所以就取所有打过标记的节点的最大值就好了。

    最后附上代码:

      1 #include<iostream>
      2 #include<cmath>
      3 #include<cstdio>
      4 #include<string>
      5 #include<cstring>
      6 #include<algorithm>
      7 #define maxn 500005
      8 using namespace std;
      9 struct edge
     10 {
     11     int next;
     12     int to;
     13     int co;
     14 }g[maxn];
     15 
     16 struct edge1
     17 {
     18     int next;
     19     int to;
     20 }g1[maxn];
     21 struct edhe
     22 {
     23     int a,b;
     24 }e[maxn];
     25 
     26 
     27 inline int read()
     28 {
     29     char c=getchar();
     30     int res=0,x=1;
     31     while(c<'0'||c>'9')
     32     {
     33         if(c=='-')
     34         x=-1;
     35         c=getchar();
     36     }
     37     while(c>='0'&&c<='9')
     38     {
     39         res=res*10+(c-'0');
     40         c=getchar();
     41     }
     42     return x*res;
     43 }
     44 
     45 int n,m,aa,bb,num,s,p,tot,top,col,num1,ans,ae,cnt;
     46 int last[maxn],a[maxn],b[maxn],dfn[maxn],st[maxn],low[maxn];
     47 int shu[maxn],d[maxn],last1[maxn],sum[maxn],vis[maxn];
     48 
     49 inline void add(int from,int to)
     50 {
     51     g[++num].next=last[from];
     52     g[num].to=to;
     53     last[from]=num;
     54 }
     55 
     56 inline void add1(int from,int to)
     57 {
     58     g1[++num1].next=last1[from];
     59     g1[num1].to=to;
     60     last1[from]=num1;
     61 }
     62 
     63 inline void tarjan(int u)
     64 {
     65     low[u]=dfn[u]=++tot;
     66     st[++top]=u;
     67     for(int i=last[u];i;i=g[i].next)
     68     {
     69         int v=g[i].to;
     70         if(!dfn[v])
     71         {
     72             tarjan(v);
     73             if(low[v]<low[u])
     74             low[u]=low[v];
     75         }
     76         else if(!g[v].co)
     77         {
     78             if(dfn[v]<low[u])
     79             low[u]=dfn[v];
     80         }
     81     }
     82     if(low[u]==dfn[u])
     83     {
     84         g[u].co=++col;
     85         while(st[top]!=u)
     86         {
     87             g[st[top]].co=col;
     88             top--;
     89         }
     90         top--;
     91     }
     92 }
     93 
     94 void dfs(int x)
     95 {
     96     for(int i=last1[x];i;i=g1[i].next)
     97     {
     98         int v=g1[i].to;
     99         if(sum[x]+shu[v]>sum[v])
    100         {
    101             sum[v]=sum[x]+shu[v];
    102             dfs(v);
    103         }
    104     }
    105 }
    106 
    107 bool cmp(edhe a,edhe b)
    108 {
    109     if(a.a==b.a)
    110     {
    111         return a.b<b.b;
    112     }
    113     else return a.a<b.a;
    114 }
    115 
    116 int main()
    117 {
    118     n=read();
    119     m=read();
    120     for(int i=1;i<=m;i++)
    121     {
    122         aa=read();bb=read();
    123         add(aa,bb);
    124     }
    125     for(int i=1;i<=n;i++)
    126     {
    127         a[i]=read();
    128     }
    129     s=read();p=read();
    130     for(int i=1;i<=p;i++)
    131     {
    132         aa=read();
    133         b[aa]=1;
    134     }
    135     for(int i=1;i<=n;i++)
    136     {
    137         if(!dfn[i])
    138         tarjan(i);
    139     }
    140     for(int i=1;i<=n;i++)
    141     {
    142         shu[g[i].co]+=a[i];
    143         if(b[i]==1)
    144         {
    145             d[g[i].co]=1;
    146         }
    147     }
    148     for(int i=1;i<=n;i++)
    149     {
    150         if(vis[i]==0) continue;
    151         for(int j=last[i];j;j=g[j].next)
    152         {
    153             int v=g[j].to;
    154             if(g[i].co!=g[v].co)
    155             {
    156                 e[++cnt].a=g[i].co;
    157                 e[cnt].b=g[v].co;
    158             }
    159         }
    160     }
    161     sort(e+1,e+cnt+1,cmp);
    162     for(int i=1;i<=cnt;i++)
    163     {
    164         if(e[i].a!=e[i-1].a||e[i].b!=e[i-1].b)
    165         {
    166             add1(e[i].a,e[i].b);
    167         }                
    168     }
    169     sum[g[s].co]=shu[g[s].co];
    170     dfs(g[s].co);
    171     for(int i=1;i<=col;i++)
    172     {
    173         if(d[i]==1)
    174         {
    175             if(ans<sum[i])
    176             ans=sum[i];
    177         }
    178     }
    179     printf("%d",ans);
    180     return 0;
    181 }
    View Code
  • 相关阅读:
    iOS 成员变量,实例变量,属性变量的区别,联系
    iOS类别(category)不能添加成员变量但是可以添加属性的问题
    iOS缓存机制详解
    ios数据缓存方法
    仿360圆圈自动隐藏效果
    html 背景透明文字不透明
    netty
    关注网站
    关注URL
    DNS之XX记录
  • 原文地址:https://www.cnblogs.com/snowy2002/p/10198751.html
Copyright © 2020-2023  润新知