bzoj1179(Atm)

---恢复内容开始---

1179: [Apio2009]Atm

Time Limit: 15 Sec  Memory Limit: 162 MB

Description

Input

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

Output

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

Sample Input

6 7
1 2
2 3
3 5
2 4
4 1
2 6
6 5
10
12
8
16
1
5
1 4
4
3
5
6

Sample Output

47

HINT

50%的输入保证N, M<=3000。所有的输入保证N, M<=500000。每个ATM机中可取的钱数为一个非负整数且不超过4000。输入数据保证你可以从市中心沿着Siruseri的单向的道路到达其中的至少一个酒吧。

这道题写了好久,终于写出来啦(哭。。。。。)

这道题思路大概是这样的,用adjacency list存完边后,先做一个tarjan并染色的预处理,然后把所有相同颜色的城市看成一个强连通分量,把这个强连通分量的颜色设置为新的地图编号为color的一个城市,然后将记录下来的原先的城市的道路,一一判断是否在新的map中是一座城市,若不是,那重新建立道路。(当然也得重新设置酒吧的位置)

最后跑一遍spfa求出每个酒吧的最大值即可(因为把强连通分量看成了一个城市了,所以不会再产生环)。

还是一样,贴代码(其实后来发现有一点可以省略不写的,就是重新设置好城市以后,把酒吧原来所在城市的的编号改成现在的就行,,还多开了一个array)

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 const int maxn=500005;
  5 using namespace std;
  6 struct node {int next,aim;};
  7 node f[maxn],e[maxn];
  8 int point,head[maxn],Low[maxn],stack[maxn],DFN[maxn],dep,top,cl[maxn],color,queue[maxn],n,m,newmoney[maxn];
  9 bool vis[maxn],bar[maxn],newbar[maxn];
 10 int x1[maxn],y1[maxn],money[maxn],start,t;
 11 long long ans,d[maxn];
 12 void add(node *array,int x,int y)
 13 {
 14   point++;
 15   array[point].next=head[x];
 16   head[x]=point;
 17   array[point].aim=y;
 18 }
 19 void tarjan(int x)
 20 {
 21     DFN[x]=Low[x]=++dep;//为节点u设定次序编号和Low初值
 22      stack[++top]=x;
 23      vis[x]=true; //将节点u压入栈中
 24     for (int i=head[x];i!=0;i=e[i].next)//枚举每一条边
 25         if (!DFN[e[i].aim])
 26         {//如果节点v未被访问过
 27             tarjan(e[i].aim);//继续向下找
 28             Low[x]=min(Low[x],Low[e[i].aim]);
 29         }
 30         else if (vis[e[i].aim])//如果节点v还在栈内
 31                 Low[x]=min(Low[x],DFN[e[i].aim]);
 32     if (DFN[x]==Low[x])//如果节点u是强连通分量的根
 33     {
 34      vis[x]=false;if(cl[x]==0)cl[x]=++color;
 35      while(stack[top]!=x)
 36      {
 37       cl[stack[top]]=color;
 38       vis[stack[top]]=false;
 39       top--;
 40      }
 41      top--;
 42     }
 43
 44 }
 45 void spfa(int x)
 46 {
 47  int Head=1,tail=2;
 48  queue[Head]=x;
 49  while(Head<tail)
 50  {
 51   for(int i=head[queue[Head]];i!=0;i=f[i].next)
 52   {
 53    int u=f[i].aim;
 54    if(d[queue[Head]]+newmoney[u]>d[u])
 55    {
 56     d[u]=d[queue[Head]]+newmoney[u];
 57     if(!vis[u])queue[tail++]=u;
 58     vis[u]=true;
 59    }
 60   }
 61   vis[queue[Head]]=false;
 62   Head++;
 63  }
 64 }
 65 int main()
 66 {
 67 scanf("%d%d",&n,&m);
 68 for(int i=1;i<=m;i++)
 69 {
 70  scanf("%d%d",&x1[i],&y1[i]);
 71  add(e,x1[i],y1[i]);
 72 }
 73 for(int i=1;i<=n;i++)
 74 {
 75  scanf("%d",&money[i]);
 76 }
 77 scanf("%d",&start);
 78 scanf("%d",&t);
 79 for(int i=1;i<=t;i++)
 80 {
 81  int l;
 82  scanf("%d",&l);
 83  bar[l]=true;
 84 }
 85 for(int i=1;i<=n;i++)
 86 if(!DFN[i])tarjan(i);
 87 memset(head,0,sizeof(head));
 88 point=0;
 89 for(int i=1;i<=m;i++)
 90 {
 91  int p=cl[x1[i]],q=cl[y1[i]];
 92  if(p!=q)add(f,p,q);
 93 }
 94 for(int i=1;i<=n;i++)
 95 newmoney[cl[i]]+=money[i];
 96 start=cl[start];
 97 for(int i=1;i<=n;i++)
 98 {
 99 if(bar[i]){
100  newbar[cl[i]]=true;
101 }
102 }
103 memset(vis,0,sizeof(vis));
104 d[start]=newmoney[start];
105 vis[start]=true;
106  spfa(start);
107  for(int i=1;i<=color;i++)
108  if(newbar[i])ans=max(ans,d[i]);
109  printf("%lld",ans);
110  return 0;
111 } 

---恢复内容结束---

时间: 2024-10-16 12:15:54

bzoj1179(Atm)的相关文章

Day22 【小程序】Credit Card(ATM),购物程序调用信用卡程序接口支付

程序介绍:  实现信用卡(ATM)常用功能:(支持多账户登陆)1.取款:2.还款:3.转账:4.查询余额:5.查询账单(流水,支持按年月日时分秒记录): 程序结构:ATM/├── README├── atm #ATM主程目录│   ├── __init__.py│   ├── bin #ATM 执行文件 目录│   │   ├── __init__.py│   │   ├── atm.py  #ATM 执行程序│   │   └── manage.py #ATM 管理端,未实现│   ├── c

Java总裁 Java连接Mysql 实例(ATM)

1 package com.jdbc; 2 3 import java.sql.Connection; 4 import java.sql.DriverManager; 5 import java.sql.ResultSet; 6 import java.sql.Statement; 7 import java.util.Scanner; 8 9 public class Atm{ 10 static Statement sc=null; 11 static Scanner sca=new Sc

Java测试总结(ATM)

package ATM; //信1705-3 20173517 赵家明import java.util.ArrayList;import java.util.Scanner;import java.util.*; @SuppressWarnings("unused")public class ATM { public static void main(String[] args) {  // TODO Auto-generated method stub  put1();   @Sup

网络基础篇之HDLC、PPP(原理)

一.广域网传输 之前讲解的都是关于局域网的数据传输,这次讲解的是广域网的传输. 广域网简称WAN,是一种跨越超大的.地域性的计算机网络集合.通常跨省.市.甚至一个国家.广域网包括很多子网,子网可以是局域网:也可以是小型的广域网. 由于串行通信有着传输距离远.成本低的特点,所以远距离.超远距离的通信中较常使用串行通信. 二.传输协议及方式 在广域网的传输中,有几种协议,本文章说明一下HDLC.PPP. 三.HDLC 1. 什么是HDLC HDLC是高级数据链路控制协议,是一种数据链路层的协议.HD

大话JS面向对象之开篇万物皆对象------(ATM取款机引发的深思)

一,总体概要 OO(面向对象)概念的提出是软件开发工程发展的一次革命,多年来我们借助它使得很多大型应用程序得以顺利实现.如果您还没有掌握并使用OO进行程序设计和开发,那么您无疑还停留在软件开发的石器时代.大多数编程语言,尤其是近年问世的一些语言,都很好的支持了面向对象,您可能对此了如执掌,但是一些语言在OO方面却无法与其它高级语言相比,在这些语言上进行面向对象程序设计和开发会有些困难,例如本文要讨论的JavaScript.JavaScript是一门古老的语言,但是随着近期Web2.0 技术的热捧

RTP与RTCP协议介绍(转载)

RTSP发起/终结流媒体.RTP传输流媒体数据 .RTCP对RTP进行控制,同步.RTP中没有连接的概念,本身并不能为按序传输数据包提供可靠的保证,也不提供流量控制和拥塞控制,这些都由RTCP来负责完成.RTSP可以对流媒体提供诸如播放.暂停.快进等操作,它负责定义具体的控制消息.操作方法.状态码等.以下为转载: 本文主要介绍RTP与RTCP协议. author: ZJ   06-11-17 Blog: [url]http://zhangjunhd.blog.51cto.com/[/url] 1

Spring学习(三)

1,Spring的事务管理机制 Spring事务管理高层抽象主要包括3个接口,Spring的事务主要是由他们共同完成的: l PlatformTransactionManager:事务管理器-主要用于平台相关事务的管理 l TransactionDefinition: 事务定义信息(隔离.传播.超时.只读)-通过配置如何进行事务管理. l TransactionStatus:事务具体运行状态-事务管理过程中,每个时间点事务的状态信息. 2, PlatformTransactionManager事

mysql事务(2)

一. 什么是事务 事务就是一段sql 语句的批处理,但是这个批处理是一个atom(原子) ,不可分割,要么都执行,要么回滚(rollback)都不执行. 二.为什么出现这种技术 为什么要使用事务这个技术呢? 现在的很多软件都是多用户,多程序,多线程的,对同一个表可能同时有很多人在用,为保持数据的一致性,所以提出了事务的概念.这样很抽象,举个例子: A 给B 要划钱,A 的账户-1000元, B 的账户就要+1000元,这两个update 语句必须作为一个整体来执行,不然A 扣钱了,B 没有加钱这

MySQL详解(13)------------事务

一. 什么是事务 事务就是一段sql 语句的批处理,但是这个批处理是一个atom(原子) ,不可分割,要么都执行,要么回滚(rollback)都不执行. 二.为什么出现这种技术 为什么要使用事务这个技术呢? 现在的很多软件都是多用户,多程序,多线程的,对同一个表可能同时有很多人在用,为保持数据的一致性,所以提出了事务的概念.这样很抽象,举个例子: A 给B 要划钱,A 的账户-1000元, B 的账户就要+1000元,这两个update 语句必须作为一个整体来执行,不然A 扣钱了,B 没有加钱这