zoukankan      html  css  js  c++  java
  • 洛谷 P3627 [APIO2009]抢掠计划 题解

    Analysis

    建图+强连通分量+SPFA求最长路

    但要保证最后到达的点中包含酒馆

    虽然思路并不难想,但要求的代码能力很高。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<queue>
      6 #define maxn 500010
      7 using namespace std;
      8 inline int read() 
      9 {
     10     int x=0;
     11     bool f=1;
     12     char c=getchar();
     13     for(; !isdigit(c); c=getchar()) if(c=='-') f=0;
     14     for(; isdigit(c); c=getchar()) x=(x<<3)+(x<<1)+c-'0';
     15     if(f) return x;
     16     return 0-x;
     17 }
     18 inline void write(int x)
     19 {
     20     if(x<0){putchar('-');x=-x;}
     21     if(x>9)write(x/10);
     22     putchar(x%10+'0');
     23 }
     24 struct node
     25 {
     26     int from,to,val,nex;
     27 }edge[2*maxn];
     28 int n,m,s,p,cnt,ans,top,inl,num;
     29 int x[maxn],y[maxn],head[maxn],dfn[maxn],low[maxn],st[maxn],inn[maxn],sum[maxn],si[maxn],money[maxn],dis[maxn];
     30 bool book[maxn],book1[maxn],bar[maxn];
     31 inline void clear()
     32 {
     33     cnt=0;
     34     memset(edge,0,sizeof(edge));
     35     memset(head,0,sizeof(head));
     36 }
     37 inline void add(int x,int y)
     38 {
     39     cnt++;
     40     edge[cnt].to=y;
     41     edge[cnt].nex=head[x];
     42     head[x]=cnt;
     43 }
     44 inline void build(int x,int y,int z)
     45 {
     46     cnt++;
     47     edge[cnt].from=x;
     48     edge[cnt].to=y;
     49     edge[cnt].val=z;
     50     edge[cnt].nex=head[x];
     51     head[x]=cnt;
     52 }
     53 inline void Tarjan(int u)
     54 {
     55     dfn[u]=low[u]=++num;
     56     st[++top]=u;
     57     for(int i=head[u];i;i=edge[i].nex)
     58     {
     59         int v=edge[i].to;
     60         if(!dfn[v])
     61         {
     62             Tarjan(v);
     63             low[u]=min(low[u],low[v]);
     64         }
     65         else if(!inn[v])
     66             low[u]=min(low[u],dfn[v]);
     67     }
     68     if(low[u]==dfn[u])
     69     {
     70         inn[u]=++inl;
     71         while(st[top]!=u)
     72         {
     73             if(bar[st[top]])book1[inl]=1;
     74             sum[inl]+=money[st[top]];
     75             inn[st[top]]=inl;
     76              --top;
     77         }
     78         if(bar[st[top]])book1[inl]=1;
     79         sum[inl]+=money[st[top]];
     80         --top;
     81     }
     82 }
     83 inline void spfa()
     84 {
     85     memset(book,0,sizeof(book));
     86     for(int i=1;i<=n;i++) dis[i]=0;
     87     queue<int> q;
     88     q.push(inn[s]);
     89     book[inn[s]]=1;
     90     dis[inn[s]]=sum[inn[s]];
     91     while(!q.empty())
     92     {
     93         for(int i=head[q.front()];i;i=edge[i].nex)
     94         {
     95             if(dis[edge[i].to]<dis[edge[i].from]+edge[i].val)
     96             {
     97                 dis[edge[i].to]=dis[edge[i].from]+edge[i].val;
     98                 if(book[edge[i].to]==0)
     99                 {
    100                     q.push(edge[i].to);
    101                     book[edge[i].to]=1;
    102                 }
    103             }
    104         }
    105         book[q.front()]=0;
    106         q.pop();
    107     }
    108 }
    109 int main()
    110 {
    111     n=read();m=read();
    112     for(int i=1;i<=m;i++)
    113     {
    114         x[i]=read();y[i]=read();
    115         add(x[i],y[i]);
    116     }
    117     for(int i=1;i<=n;i++)money[i]=read();
    118     s=read();p=read();
    119     
    120     for(int i=1;i<=p;i++)
    121     {
    122         int x;
    123         x=read();
    124         bar[x]=1;
    125     }
    126     for(int i=1;i<=n;i++)
    127         if(!dfn[i])
    128             Tarjan(i);
    129     
    130     clear();
    131     for(int i=1;i<=m;i++)
    132         if(inn[x[i]]!=inn[y[i]])
    133             build(inn[x[i]],inn[y[i]],sum[inn[y[i]]]);
    134     spfa();
    135     for(int i=1;i<=inl;i++)
    136         if(book1[i]==1)
    137             ans=max(ans,dis[i]);
    138     write(ans);
    139     return 0;
    140 }
    请各位大佬斧正(反正我不认识斧正是什么意思)
  • 相关阅读:
    Leetcode 233 Number of Digit One
    获取各种常见形状的位图
    关于编程
    LintCode-第k大元素
    基于IBM Bluemix的数据缓存应用实例
    LeakCanary:简单粗暴的内存泄漏检測工具
    MFC,C++,VC++,VS2010 之间究竟是什么关系
    我对高考考场制度(比方是否同意迟到、忘带考证、上厕所)优化的点滴思考,不一定非常有道理
    ural 1989(树状数组+多项式hash)
    TI C66x DSP 系统events及其应用
  • 原文地址:https://www.cnblogs.com/handsome-zyc/p/11250401.html
Copyright © 2011-2022 走看看