zoukankan      html  css  js  c++  java
  • tarjan 算法求强连通分量

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 using namespace std;
     4 const int P=1e6;
     5 const int N=2e6+5;
     6 const int M=2e6+5;
     7 const int inf=0x3f3f3f3f;
     8 struct edge
     9 {
    10     int f,t,next;
    11     ll v;
    12 }e[M];
    13 int n,m,tot,all,s,cnt,head[N],dfn[N],low[N],st[N],id[N];
    14 int dindex;
    15 bool inst[N];
    16 ll num[N],sum[100005],val[N];
    17 void add(int f,int t,ll v)
    18 {
    19     e[tot].f=f; e[tot].t=t; e[tot].v=v;
    20     e[tot].next=head[f]; head[f]=tot++;
    21 }
    22 void tarjan(int v)
    23 {
    24     dindex++;
    25     dfn[v]=low[v]=dindex;
    26     st[all++]=v; inst[v]=true;
    27     for(int i=head[v];~i;i=e[i].next)
    28     {
    29         int nx=e[i].t;
    30         if(!dfn[nx])
    31         {
    32             tarjan(nx);
    33             low[v]=min(low[v],low[nx]);
    34         }
    35         else if(inst[nx]) low[v]=min(low[v],dfn[nx]);
    36     }
    37     if(dfn[v]==low[v])
    38     {
    39         cnt++;
    40         while(1)
    41         {
    42             int cur=st[--all];
    43             inst[cur]=false;
    44             id[cur]=cnt;
    45             if(cur==v) break;
    46         }
    47     }
    48 }
    49 ll work(ll x)
    50 {
    51     ll ans=0;
    52     int item=lower_bound(num,num+15001,x)-num;
    53     ans-=sum[item];
    54     ans+=x*(item+1);
    55     ans+=num[item]-x;
    56     return ans;
    57 }
    58 ll dfs(int v)
    59 {
    60     ll res=0;
    61     dfn[v]=1;
    62     for(int i=head[v];~i;i=e[i].next)
    63     {
    64         int nx=e[i].t;
    65         if(!dfn[nx]) res=max(res,e[i].v+dfs(nx));
    66         else res=max(res,val[nx]+e[i].v);
    67     }
    68     val[v]+=res;
    69     return val[v];
    70 }
    71 int main()
    72 {
    73     num[1]=1; cnt=0; all=0; tot=0; dindex=0;
    74     for(int i=1;i<=15000;i++) num[i]=num[i-1]+i,sum[i]=sum[i-1]+num[i];
    75     memset(head,-1,sizeof(head));
    76     scanf("%d%d",&n,&m);
    77     for(int i=1;i<=m;i++)
    78     {
    79         int f,t; ll v;
    80         scanf("%d%d%lld",&f,&t,&v);
    81         add(f,t,v);
    82     }
    83     scanf("%d",&s);
    84     tarjan(s);
    85     int up=tot;
    86     for(int i=0;i<up;i++)
    87     {
    88         int a=e[i].f,b=e[i].t;
    89         if(!id[a] || !id[b]) continue;
    90         if(id[a]==id[b]) val[id[a]+P]+=work(e[i].v);
    91         else if(id[a]<id[b]) add(id[b]+P,id[a]+P,e[i].v);
    92         else add(id[a]+P,id[b]+P,e[i].v);
    93     }
    94     ll ans=dfs(id[s]+P);
    95     printf("%lld
    ",ans);
    96     return 0;
    97 }
    View Code
  • 相关阅读:
    js获取url参数
    css3 text-shadow字体阴影讲解
    css3 box-shadow阴影(外阴影与外发光)讲解
    【leetcode刷题笔记】Palindrome Partitioning II
    【leetcode刷题笔记】Minimum Window Substring
    【leetcode刷题笔记】Interleaving String
    【leetcode刷题笔记】Wildcard Matching
    【leetcode刷题笔记】Regular Expression Matching
    【leetcode刷题笔记】Insert Interval
    【leetcode刷题笔记】Multiply Strings
  • 原文地址:https://www.cnblogs.com/CJLHY/p/7744907.html
Copyright © 2011-2022 走看看