zoukankan      html  css  js  c++  java
  • bzoj 1179 Atm

    题目大意:

    一个有向图,有些点可以作为终点,每个点有权值,每个点和边可以走很多遍,点走过之后再走点权不会计入分数

    从一个点开始,求一个路径使这条路径的分数最大且终点是给定的点之一

    输出这个路径长度

    思路:

    首先tarjan缩点

    然后在新图上用spfa跑最长路(开始非常naive以为用dfs就可以

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstdlib>
     5 #include<cstring>
     6 #include<algorithm>
     7 #include<queue>
     8 #include<vector>
     9 #define ll long long 
    10 #define MAXN 500100
    11 #define inf 2139062143
    12 using namespace std;
    13 inline int read()
    14 {
    15     int x=0,f=1;char ch=getchar();
    16     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    17     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    18     return x*f;
    19 }
    20 int n,m,fst[MAXN],nxt[MAXN],to[MAXN],cnt,val[MAXN],bar[MAXN],s,Fst[MAXN],Nxt[MAXN],To[MAXN];
    21 int ans,dfn[MAXN],low[MAXN],vis[MAXN],stp,top,st[MAXN],sum[MAXN],ok[MAXN],scc,bl[MAXN];
    22 int dis[MAXN],q[MAXN],head,tail;
    23 void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;}
    24 void Add(int u,int v) {Nxt[++cnt]=Fst[u],Fst[u]=cnt,To[cnt]=v;}
    25 void tarjan(int x)
    26 {
    27     dfn[x]=low[x]=++stp,vis[x]=1,st[++top]=x;
    28     for(int i=fst[x];i;i=nxt[i])
    29         if(!dfn[to[i]]) {tarjan(to[i]);low[x]=min(low[x],low[to[i]]);}
    30         else if(vis[to[i]]) low[x]=min(low[x],dfn[to[i]]);
    31     if(low[x]==dfn[x])
    32     {
    33         scc++;int now=0;
    34         while(now!=x)
    35         {
    36             now=st[top--],vis[now]=0,sum[scc]+=val[now],bl[now]=scc;
    37             if(bar[now]) ok[scc]=1;
    38         }
    39     }
    40 }
    41 void build()
    42 {
    43     cnt=0;
    44     for(int i=1;i<=n;i++)
    45         for(int j=fst[i];j;j=nxt[j])
    46             if(bl[i]!=bl[to[j]]) Add(bl[i],bl[to[j]]);
    47 }
    48 void spfa()
    49 {
    50     s=bl[s],head=tail=1,q[tail]=s,vis[s]=1;
    51     while(head<=tail)
    52     {
    53         int x=q[head++];vis[x]=0;
    54         for(int i=Fst[x];i;i=Nxt[i])
    55             if(dis[To[i]]<dis[x]+sum[To[i]]) 
    56             {
    57                 dis[To[i]]=dis[x]+sum[To[i]];
    58                 if(!vis[To[i]]) {vis[To[i]]=1,q[++tail]=To[i];}
    59             }
    60     }
    61 }
    62 int main()
    63 {
    64     n=read(),m=read();int a,b,t;
    65     while(m--) {a=read(),b=read();add(a,b);}
    66     for(int i=1;i<=n;i++) val[i]=read();
    67     s=read(),t=read();
    68     for(int i=1;i<=t;i++) bar[read()]=1;
    69     for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i);
    70     build();spfa();
    71     for(int i=1;i<=scc;i++) if(ok[i]) ans=max(ans,dis[i]);
    72     printf("%d",ans+sum[s]);
    73 }
    View Code
  • 相关阅读:
    asp.net mvc(2013424)——基本知识
    asp.net mvc(2013425)——使用模板页
    jquery实现tab切换核心代码
    asp.net mvc(2013422 )——准备入门
    也说C#串行化
    Net Assembly.GetExecutingAssembly() 和 Assembly.GetCallingAssembly()的区别
    log (一)
    C# 重载和从写的区别
    log4net
    C# 反射
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/8986820.html
Copyright © 2011-2022 走看看