• luogu3119/bzoj3887 草鉴定 (tarjan缩点+spfa)


    首先缩一波点,就变成了一个DAG,边权是出点的大小

    那我们走到某个点的时候可能会有两种状态:已经走过反边或者没走过

    于是就把一个点拆成两层(x和x+N),第二层的点表示我已经走过反边了,每层中的边和原来一样,但对于边(u,v),我们连一个(v,u+N),表示走了这条边的反边,这条边的边权是u的大小

    因为DAG中没有环,所以权值不会被重复计算

    然后spfa算从belong[1]到bel[1]+N的最长路就行了

     1 #include<bits/stdc++.h>
     2 #define CLR(a,x) memset(a,x,sizeof(a))
     3 using namespace std;
     4 typedef long long ll;
     5 typedef pair<int,int> pa;
     6 const int maxn=1e5+10;
     7 
     8 inline ll rd(){
     9     ll x=0;char c=getchar();int neg=1;
    10     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
    11     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
    12     return x*neg;
    13 }
    14 
    15 struct Edge{
    16     int ne,b,l;
    17 }eg[maxn*3];
    18 int egh[maxn*2],ect;
    19 int eg1[maxn][2],egh1[maxn],ect1;
    20 int N,M,dfn[maxn],low[maxn],stk[maxn],sh,tot,bel[maxn],pct,siz[maxn];
    21 bool instk[maxn];
    22 
    23 inline void adeg1(int a,int b){
    24     eg1[++ect1][0]=b,eg1[ect1][1]=egh1[a],egh1[a]=ect1;
    25 }
    26 inline void adeg(int a,int b,int c){
    27     eg[++ect].b=b,eg[ect].l=c,eg[ect].ne=egh[a],egh[a]=ect;
    28 }
    29 
    30 void tarjan(int x){
    31     dfn[x]=low[x]=++tot,instk[x]=1,stk[++sh]=x;
    32     for(int i=egh1[x];i;i=eg1[i][1]){
    33         int b=eg1[i][0];
    34         if(!dfn[b]) tarjan(b),low[x]=min(low[x],low[b]);
    35         else if(instk[b]) low[x]=min(low[x],dfn[b]);
    36     }
    37     if(dfn[x]==low[x]){
    38         ++pct;
    39         while(1){
    40             instk[stk[sh]]=0;
    41             bel[stk[sh]]=pct;siz[pct]++;
    42             if(stk[sh--]==x) break;
    43         }
    44     }
    45 }
    46 
    47 queue<int> q;
    48 int dis[maxn*2];
    49 bool flag[maxn*2];
    50 inline void spfa(){
    51     q.push(bel[1]);
    52     while(!q.empty()){
    53         int p=q.front();q.pop();
    54         flag[p]=0;
    55         // printf("!%d
    ",p);
    56         for(int i=egh[p];i;i=eg[i].ne){
    57             int b=eg[i].b;
    58             if(dis[b]<dis[p]+eg[i].l){
    59                 dis[b]=dis[p]+eg[i].l;
    60                 if(!flag[b]) q.push(b);
    61                 flag[b]=1;
    62             }
    63         }
    64     }
    65 }
    66 
    67 int main(){
    68     // freopen("testdata.in","r",stdin);
    69     int i,j,k;
    70     N=rd(),M=rd();
    71     for(i=1;i<=M;i++){
    72         int a=rd(),b=rd();
    73         adeg1(a,b);
    74     }
    75     for(i=1;i<=N;i++)
    76         if(!dfn[i]) tarjan(i);
    77     for(i=1;i<=N;i++){
    78         int a=bel[i];
    79         for(j=egh1[i];j;j=eg1[j][1]){
    80             int b=bel[eg1[j][0]];
    81             if(a==b) continue;
    82             adeg(a,b,siz[b]);
    83             adeg(a+N,b+N,siz[b]);
    84             adeg(b,a+N,siz[a]);
    85         }
    86     }
    87     spfa();
    88     printf("%d
    ",dis[bel[1]+N]);
    89     return 0;
    90 }
  • 相关阅读:
    VMware Workstations Pro15.1.0并解锁Unlock3.0.2 安装黑苹果
    正则表达式对字符串匹配
    Linq操作
    C#模糊查询绑定datagridview
    wpf的datepicker处理
    动态调用webservice,不需要添加Web References
    C#调用sap接口及返回数据到sap
    C#中文件管理的运用(Twelfth Day)
    C#中继承,集合(Eleventh day)
    C#中字符串的处理,对象的引用及继承(Tenth day)
  • 原文地址:https://www.cnblogs.com/Ressed/p/9934890.html
Copyright © 2020-2023  润新知