• bzoj1179[Apio2009]Atm


    bzoj1179[Apio2009]Atm

    题意:

    给个有向图,每个点有个点权,有些点有酒吧。现在求一个人从任意一点出发获得点权的最大和。要求每个点的点权只能获得一次,且路径最后必须在酒吧结束,可以重复经过点和边。n,m≤500000。

    题解:

    tarjan缩点之后跑spfa,注意不能用dijkstra,因为求正权边的最长路相当于求最短路时有负权边。

    代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <stack>
     5 #include <queue>
     6 #define inc(i,j,k) for(int i=j;i<=k;i++)
     7 #define maxn 500010
     8 #define INF 0x3fffffff
     9 using namespace std;
    10 
    11 inline int read(){
    12     char ch=getchar(); int f=1,x=0;
    13     while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
    14     while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    15     return f*x;
    16 }
    17 struct e{int t,n;}es[2][maxn]; int g[2][maxn],ess[2];
    18 void pe(int f,int t,bool o){es[o][++ess[o]]=(e){t,g[o][f]}; g[o][f]=ess[o];}
    19 int v[2][maxn],scc[maxn],tot,n,m,s,p,ans;
    20 bool ins[maxn]; int tim,low[maxn],dfn[maxn]; stack<int>st;
    21 void tarjan(int x){
    22     ins[x]=1; low[x]=dfn[x]=++tim; st.push(x);
    23     for(int i=g[0][x];i;i=es[0][i].n){
    24         if(!dfn[es[0][i].t])tarjan(es[0][i].t),low[x]=min(low[x],low[es[0][i].t]);
    25         else if(ins[es[0][i].t])low[x]=min(low[x],dfn[es[0][i].t]);
    26     }
    27     if(low[x]==dfn[x]){
    28         tot++;
    29         while(!st.empty()){
    30             int y=st.top(); st.pop(); ins[y]=0; scc[y]=tot;
    31             v[1][tot]+=v[0][y]; if(x==y)break;
    32         }
    33     }
    34 }
    35 int d[maxn]; bool inq[maxn]; deque<int>q;
    36 void spfa(int s){
    37     inc(i,1,tot)d[i]=-1; d[s]=v[1][s]; inq[s]=1; q.push_back(s);
    38     while(!q.empty()){
    39         int x=q.front(); q.pop_front(); inq[x]=0;
    40         for(int i=g[1][x];i;i=es[1][i].n)if(d[es[1][i].t]<d[x]+v[1][es[1][i].t]){
    41             d[es[1][i].t]=d[x]+v[1][es[1][i].t];
    42             if(!inq[es[1][i].t]){
    43                 if(!q.empty()&&d[es[1][i].t]<d[q.front()])q.push_front(es[1][i].t);else q.push_back(es[1][i].t);
    44                 inq[es[1][i].t]=1;
    45             }
    46         }
    47     }
    48 }
    49 int main(){
    50     n=read(); m=read(); inc(i,1,m){int x=read(),y=read(); pe(x,y,0);} inc(i,1,n)v[0][i]=read();
    51     s=read(); p=read(); inc(i,1,n)if(!dfn[i])tarjan(i);
    52     inc(i,1,n){
    53         for(int j=g[0][i];j;j=es[0][j].n)
    54             if(scc[i]!=scc[es[0][j].t])pe(scc[i],scc[es[0][j].t],1);
    55     }
    56     spfa(scc[s]); inc(i,1,p){int x=read(); if(d[scc[x]]!=-1)ans=max(ans,d[scc[x]]);}
    57     printf("%d",ans); return 0;
    58 }

    20161114

  • 相关阅读:
    mysql锁表与解锁
    问题汇总
    安装一台Centos7桌面版的跳板机
    Centos7二进制部署k8s-v1.20.2 ipvs版本(部署mysql、nacos)
    Centos7二进制部署k8s-v1.20.2 ipvs版本(Prometheus监控k8s)
    CV2 安装异常
    PostgreSQL VACUUM 没有效果(无法清理死元组)的原因
    SQL Server 进程运行状态解析
    mysql 几种启动和关闭mysql服务的方法和区别
    MySQL学习(九)小结(转载)
  • 原文地址:https://www.cnblogs.com/YuanZiming/p/6067187.html
Copyright © 2020-2023  润新知