zoukankan      html  css  js  c++  java
  • Tarjan缩点模板 (洛谷P3387)

    题目背景

    缩点+DP

    题目描述

    给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大。你只需要求出这个权值和。

    允许多次经过一条边或者一个点,但是,重复经过的点,权值只计算一次。

    输入输出格式

    输入格式:

    第一行,n,m

    第二行,n个整数,依次代表点权

    第三至m+2行,每行两个整数u,v,表示u->v有一条有向边

    输出格式:

    共一行,最大的点权之和。

    输入输出样例

    输入样例#1: 复制
    2 2
    1 1
    1 2
    2 1
    输出样例#1: 复制
    2

    说明

    n<=10^4,m<=10^5,|点权|<=1000 算法:Tarjan缩点+DAGdp

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #include<queue>
      5 #define maxn 100010
      6 using namespace std;
      7 inline int read()
      8 {
      9     int x=0,f=1;
     10     char ch=getchar();
     11     while(ch<'0'||ch>'9')
     12     {
     13         if(ch=='-') f=-1;
     14         ch=getchar();
     15     }
     16     while(ch>='0'&&ch<='9')
     17     {
     18         x=x*10+ch-'0';
     19         ch=getchar();
     20     }
     21     return x*f;
     22 }
     23 int head[maxn],ecnt,vis[maxn],dis[maxn],low[maxn],dfn[maxn],stk[maxn],tot,colortm,color[maxn],top,f[maxn],ans,w[maxn],x[maxn],y[maxn],n,m;
     24 struct edge
     25 {
     26     int u,v,next;
     27 }E[maxn];
     28 void add(int u,int v)
     29 {
     30     E[++ecnt].u=u;
     31     E[ecnt].v=v;
     32     E[ecnt].next=head[u];
     33     head[u]=ecnt;
     34 }
     35 void tarjan(int u)
     36 {
     37     vis[u]=1;
     38     stk[++top]=u;
     39     low[u]=dfn[u]=++tot;
     40     for(int i=head[u];i;i=E[i].next)
     41     {
     42         int v=E[i].v;
     43         if(!dfn[v])
     44         {
     45             tarjan(v);
     46             low[u]=min(low[u],low[v]);
     47         }
     48         else if(vis[v]) low[u]=min(low[u],dfn[v]);
     49     }
     50     if(dfn[u]==low[u])
     51     {
     52         ++colortm;
     53         vis[u]=0;
     54         while(stk[top+1]!=u)
     55         {
     56             vis[stk[top]]=0;
     57             color[stk[top]]=colortm;
     58             f[colortm]+=w[stk[top]];
     59             ans=max(ans,f[colortm]);
     60             top--;
     61         }
     62     }
     63 }
     64 void bfs(int x)
     65 {
     66     memset(vis,0,sizeof(vis));
     67     memset(dis,0,sizeof(dis));
     68     queue<int>q;
     69     q.push(x);
     70     vis[x]=1;
     71     dis[x]=f[x];
     72     while(!q.empty())
     73     {
     74         int u=q.front();
     75         for(int i=head[u];i;i=E[i].next)
     76         {
     77             int v=E[i].v;
     78             if(dis[v]<dis[u]+f[v])
     79             {
     80                 dis[v]=dis[u]+f[v];
     81                 if(!vis[v]) 
     82                 {
     83                     q.push(v);
     84                     vis[v]=1;
     85                 }
     86              } 
     87         }
     88         q.pop();
     89         vis[u]=0;
     90     }
     91     for(int i=1;i<=colortm;++i) ans=max(ans,dis[i]);
     92 }
     93 int main()
     94 {
     95     n=read();m=read();
     96     for(int i=1;i<=n;++i) w[i]=read();
     97     for(int i=1;i<=m;++i) 
     98     {
     99         int a=read(),b=read();
    100         add(a,b);
    101         x[i]=a;
    102         y[i]=b;
    103     }
    104     for(int i=1;i<=n;++i)
    105     {
    106         if(!dfn[i]) tarjan(i);
    107     }
    108     memset(head,0,sizeof(head));
    109     memset(E,0,sizeof(E));
    110     ecnt=0;
    111     for(int i=1;i<=m;++i)
    112     {
    113         if(color[x[i]]!=color[y[i]])
    114         {
    115             add(color[x[i]],color[y[i]]);
    116         }
    117     }
    118     
    119     for(int i=1;i<=colortm;++i)
    120         bfs(i);
    121     printf("%d
    ",ans);
    122     return 0;
    123  } 
    View Code
  • 相关阅读:
    【POJ】1067 取石子游戏(博弈论)
    【POJ】2348 Euclid's Game(扩欧)
    【POJ】1061 青蛙的约会 / 【BZOJ】1477(扩欧)
    【POJ】3090 Visible Lattice Points(欧拉函数)
    【BZOJ】2190 [SDOI2008]仪仗队(欧拉函数)
    【POJ】2115 C Looooops(扩欧)
    【BZOJ】1015 [JSOI2008]星球大战starwar(并查集+离线处理)
    [BZOJ4822][Cqoi2017]老C的任务
    [BZOJ1001][BeiJing2006]狼抓兔子
    [BZOJ1188][HNOI2007]分裂游戏
  • 原文地址:https://www.cnblogs.com/mljkw-gsry/p/8323944.html
Copyright © 2011-2022 走看看