【强连通缩点+最长路】抢掠计划

原创 2012年03月29日 09:01:23

抢掠计划
Siruseri城中的道路都是单向的。不同的道路由路口连接。按照法律的规定,
在每个路口都设立了一个 Siruseri 银行的 ATM 取款机。令人奇怪的是,Siruseri
的酒吧也都设在路口,虽然并不是每个路口都设有酒吧。
Banditji 计划实施 Siruseri有史以来最惊天动地的 ATM 抢劫。他将从市中心
出发,沿着单向道路行驶,抢劫所有他途径的ATM 机,最终他将在一个酒吧庆
祝他的胜利。
使用高超的黑客技术,他获知了每个ATM 机中可以掠取的现金数额。他希
望你帮助他计算从市中心出发最后到达某个酒吧时最多能抢劫的现金总数。他可
以经过同一路口或道路任意多次。但只要他抢劫过某个 ATM 机后,该 ATM 机
里面就不会再有钱了。
例如,假设该城中有6个路口,道路的连接情况如下图所示: 


 
市中心在路口 1,由一个入口符号→来标识,那些有酒吧的路口用双圈来表
示。每个ATM机中可取的钱数标在了路口的上方。在这个例子中,Banditji 能抢
劫的现金总数为47,实施的抢劫路线是:1-2-4-1-2-3-5。
输入格式
第一行包含两个整数 N、M。N 表示路口的个数,M表示道路条数。接下来
M行,每行两个整数,这两个整数都在 1到 N 之间,第i+1 行的两个整数表示第
i 条道路的起点和终点的路口编号。接下来 N 行,每行一个整数,按顺序表示每
个路口处的ATM机中的钱数。接下来一行包含两个整数 S、P,S表示市中心的
编号,也就是出发的路口。P表示酒吧数目。接下来的一行中有 P个整数,表示
P个有酒吧的路口的编号。
输出格式
输出一个整数,表示 Banditji 从市中心开始到某个酒吧结束所能抢劫的最多
的现金总数。

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


和上一道题如出一辙,此题是一个简化版本,不用再赘述。

只是因为ans = MAX(ans,dist[Belong[bar[i]]]+size[Belong[S]]);  

打成了ans = MAX(ans,dist[bar[i]]+size[Belong[S]]);    而悲剧地爆零了


#pragma comment(linker, "/STACK:1024000000,1024000000") 
#include <cstdio>
#include <map>

const long maxn = 500010;
const long MOD = 500010;
typedef long long ll;
long n;long m;
long S;long P;
long money[maxn];
long bar[maxn];
long DFN[maxn];
long LOW[maxn];
bool InStack[maxn];
long Stack[maxn];
long top  = 0;
long TIME = 0;
long Bcnt = 0;
long Belong[maxn];
long size[maxn];
long que[MOD];
bool vis[maxn];
long dist[maxn];
std::map<ll,bool> connected;
#define POS(a,b) (((ll)a-1)*(ll)m+(ll)b-1ll)
#define MIN(a,b) (a<b?a:b)
#define MAX(a,b) (a>b?a:b)

struct node
{
	long index;
	node* next;	
};
node* head[maxn];
node* head2[maxn];

void insert(long a,long b)
{
	node* tmp = new node;
	tmp->index = b;
	tmp->next = head[a];
	head[a] = tmp;
}

void init()
{
	scanf("%ld%ld",&n,&m);
	for (long i=1;i<m+1;i++)
	{
		long a;long b;
		scanf("%ld%ld",&a,&b);
		insert(a,b);
	}
	for (long i=1;i<n+1;i++)
	{
		scanf("%ld",money+i);
	}
	scanf("%ld%ld",&S,&P);
	for (long i=1;i<P+1;i++)
	{
		scanf("%ld",bar+i);
	}
}

void tarjan(long u)
{
	DFN[u] = LOW[u] = ++TIME;
	InStack[u] = true;
	Stack[++top] = u;
	for (node* next=head[u];next;next=next->next)
	{
		long v = next->index;
		if (!DFN[v])
		{
			tarjan(v);
			LOW[u] = MIN(LOW[u],LOW[v]);
		}
		else if(InStack[v])
		{
			LOW[u] = MIN(LOW[u],DFN[v]);
		}
	}
	if (DFN[u] == LOW[u])
	{
		++Bcnt;
		long v;
		do
		{
			v = Stack[top--];
			InStack[v]= false;
			Belong[v] = Bcnt;
			size[Bcnt]+=money[v]; 
		}while(v != u);
	}
}

void SPFA()
{
	long l = 0;
	long r = 0;
	que[++r] = Belong[S];
	while (l != r)
	{
		l = (l+1) % MOD;
		long u = que[l];
		vis[u] = false;
		for (node* vv=head2[u];vv;vv=vv->next)
		{
			long v = vv->index;
			if (dist[v]<dist[u]+size[v])
			{
				dist[v]=dist[u]+size[v];
				if (!vis[v])
				{
					vis[v] = true;
					r = (r+1) % MOD;
					que[r] = v;
				}
			}
		}
	}	
}

void insert2(long a,long b)
{
	node* tmp = new node;
	tmp->index = b;
	tmp->next = head2[a];
	head2[a] = tmp;
}

void rebuild()
{
	for (long u=1;u<n+1;u++)
	{
		for (node* vv=head[u];vv;vv=vv->next)
		{
			long v = vv->index;
			long B1 = Belong[u];
			long B2 = Belong[v];
			if (B1 != B2 && !connected[POS(B1,B2)])
			{
				connected[POS(B1,B2)] = true;
				insert2(B1,B2);
			}
		}
	}
}

int main()
{
	freopen("atm.in","r",stdin);
	freopen("atm.out","w",stdout); 
	init();
	for (long i=1;i<n+1;i++)
		if (!DFN[i]) tarjan(i);
	rebuild();
	SPFA();
	long ans = 0;
	for (long i=1;i<P+1;i++)
	{
		ans = MAX(ans,dist[Belong[bar[i]]]+size[Belong[S]]);	
	}
	printf("%ld",ans);
	return 0;
}





版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

APIO 2009 抢掠计划 强联通缩点+最长路

Description Siruseri城中的道路都是单向的。不同的道路由路口连接。按照法律的规定,在每个路口都设立了一个Siruseri银行的ATM取款机。令人奇怪的是,Siruseri的酒吧...

【BZOJ1179】【Apio2009】Atm 强连通分量缩点+拓扑DP/拓扑最长路 kosaraju+tarjan+dfs转非递归三种代码

kosaraju、tarjan、kosaraju dfs转非递归,三种代码。。。 可以有效对付卡系统栈的管理员。。。

poj 3592 Instantaneous Transference 强连通+缩点+最长路

题目链接:http://poj.org/problem?id=3592 题目大意 :坦克一开始在(0,0),只可以向右边或下边走,走过的时候可以获得该格子上面的矿物(只能采集一次,之后矿物消失)。 ...

【强连通缩点+最长路】Instantaneous Transference

Instantaneous Transference Time Limit: 5000MS   Memory Limit: 65536K Total Submissio...

ZOJ 3795 Grouping 强连通缩点 + DAG最长路

Grouping Time Limit: 2 Seconds      Memory Limit: 65536 KB Suppose there are N people in ZJ...

POJ 3160 Father Christmas flymouse 强连通+最长路

题意:给你一些点,每个点有一个权值,可正可负,再给你点的关系,可以选择其中的点,每个点只能被选择一次,然后找一个source,走一条路,然后求最大的边权路径。 思路:1.负值,不选        ...

UVA11324_The Largest Clique_tarjan求强连通分量+DP求最长路

题意: 给一个图,求它的一个最大子图,使得图中任意两点之间都至少有一条路径【注意是两点之间有路径,而不是可以到达任意一点,所以不是强连通分量】 【PS:题中给的传递闭包其实是个迷惑,没有用,因为在原图...

【POJ】3592 Instantaneous Transference 强连通+最长路

Instantaneous Transference Time Limit: 5000MS Memory Limit: 65536K Total Submissi...

【POJ】2762 Going from u to v or from v to u? 强连通+最长路

Going from u to v or from v to u? Time Limit: 2000MS Memory Limit: 65536...

POJ 2762 Going from u to v or from v to u? 强连通分量+DAG最长路

题意:给你一个有向图,问你是否对于任意两个点都有一条u->v或者v->u的路。思路:对于一个强联通分量,里面的点一定满足条件,我们可以把他们缩点,而对于不在同一联通分量的点,如果存在一条路径,使得这条...
  • s_h_r
  • s_h_r
  • 2015-10-12 10:49
  • 186
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)