码迷,mamicode.com
首页 > Windows程序 > 详细

洛谷3627 [APIO2009]抢掠计划

时间:2017-12-15 22:43:44      阅读:292      评论:0      收藏:0      [点我收藏+]

标签:post   ret   clu   str   insert   memset   tarjan   set   logs   

题目描述

技术分享图片

输入格式:

第一行包含两个整数 N、M。N 表示路口的个数,M 表示道路条数。接下来 M 行,每行两个整数,这两个整数都在 1 到 N 之间,第 i+1 行的两个整数表示第 i 条道路的起点和终点的路口编号。接下来 N 行,每行一个整数,按顺序表示每 个路口处的 ATM 机中的钱数。接下来一行包含两个整数 S、P,S 表示市中心的 编号,也就是出发的路口。P 表示酒吧数目。接下来的一行中有 P 个整数,表示 P 个有酒吧的路口的编号。

输出格式:

输出一个整数,表示 Banditji 从市中心开始到某个酒吧结束所能抢劫的最多 的现金总数。

 

缩点之后跑spfa,原来我脑残跑最短路挑错挑了半天

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#define maxn 500005
using namespace std;
int dfn[maxn],low[maxn],stk[maxn],bel[maxn];
int n,m,cnt,ind,top,tot;
int head[maxn],dis[maxn],w1[maxn],w2[maxn],x[maxn],y[maxn];
bool vis[maxn],inq[maxn],ok1[maxn],ok2[maxn];
struct edge{
    int next,to,w;
}e[maxn];
void insert(int u,int v,int w){
    cnt++;
    e[cnt].next=head[u];e[cnt].to=v;e[cnt].w=w;
    head[u]=cnt;
}
void tarjan(int x){
    stk[++top]=x;
    dfn[x]=low[x]=++ind;
    inq[x]=1;
    for(int i=head[x];i;i=e[i].next){
        int s=e[i].to;
        if(!dfn[s]){
            tarjan(s);
            low[x]=min(low[x],low[s]);
        }
        else if(inq[s]){
            low[x]=min(low[x],dfn[s]);
        }
    }
    int now=0;
    if(dfn[x]==low[x]){
        tot++;
        while(now!=x){
            now=stk[top];top--;
            bel[now]=tot;
            inq[now]=0;
            w2[tot]+=w1[now];
            if(ok1[now]){
                ok2[tot]=1;
            }
        }
    }
}
void spfa(int x){
    queue<int>q;
    memset(dis,0xef,sizeof dis);
    memset(vis,0,sizeof vis);
    q.push(x);
    vis[x]=1;dis[x]=w2[x];
    while(!q.empty()){
    int now=q.front();vis[now]=0;q.pop();
    for(int i=head[now];i;i=e[i].next){
        int s=e[i].to;
        if(dis[s]<dis[now]+e[i].w){
            dis[s]=dis[now]+e[i].w;
            if(!vis[s]){
                vis[s]=1;
                q.push(s);
                }
            }
        }
    }
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        scanf("%d%d",&x[i],&y[i]);
        insert(x[i],y[i],0);
    }
    for(int i=1;i<=n;i++){
        scanf("%d",&w1[i]);
    }
    int u,p,v;
    scanf("%d%d",&u,&p);
    for(int i=1;i<=p;i++){
        scanf("%d",&v);
        ok1[v]=1;
    }
    for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i);
    cnt=0;
    memset(head,0,sizeof head);
    memset(e,0,sizeof e);
    for(int i=1;i<=m;i++){
        if(bel[x[i]]!=bel[y[i]])insert(bel[x[i]],bel[y[i]],w2[bel[y[i]]]);
    }
    spfa(bel[u]);
    int ans=0;
    for(int i=1;i<=tot;i++){
        if(ok2[i]){
            ans=max(ans,dis[i]);
        }
    }
    printf("%d",ans);
    return 0;
}

 

洛谷3627 [APIO2009]抢掠计划

标签:post   ret   clu   str   insert   memset   tarjan   set   logs   

原文地址:http://www.cnblogs.com/Elfish/p/8044924.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!