tarjan + 缩点

D - Cow Ski Area

Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d
& %I64u

Submit Status

Description

Farmer John‘s cousin, Farmer Ron, who lives in the mountains of Colorado, has recently taught his cows to ski. Unfortunately, his cows are somewhat timid and are afraid to ski among crowds of people at the local resorts, so FR has decided to construct his own
private ski area behind his farm.

FR‘s ski area is a rectangle of width W and length L of ‘land squares‘ (1 <= W <= 500; 1 <= L <= 500). Each land square is an integral height H above sea level (0 <= H <= 9,999). Cows can ski horizontally and vertically between any two adjacent land squares,
but never diagonally. Cows can ski from a higher square to a lower square but not the other way and they can ski either direction between two adjacent squares of the same height.

FR wants to build his ski area so that his cows can travel between any two squares by a combination of skiing (as described above) and ski lifts. A ski lift can be built between any two squares of the ski area, regardless of height. Ski lifts are bidirectional.
Ski lifts can cross over each other since they can be built at varying heights above the ground, and multiple ski lifts can begin or end at the same square. Since ski lifts are expensive to build, FR wants to minimize the number of ski lifts he has to build
to allow his cows to travel between all squares of his ski area.

Find the minimum number of ski lifts required to ensure the cows can travel from any square to any other square via a combination of skiing and lifts.

Input

* Line 1: Two space-separated integers: W and L

* Lines 2..L+1: L lines, each with W space-separated integers corresponding to the height of each square of land.

Output

* Line 1: A single integer equal to the minimal number of ski lifts FR needs to build to ensure that his cows can travel from any square to any other square via a combination of skiing and ski lifts

Sample Input

9 3
1 1 1 2 2 2 1 1 1
1 2 1 2 3 2 1 2 1
1 1 1 2 2 2 1 1 1

Sample Output

3

Hint

This problem has huge input data,use scanf() instead of cin to read data to avoid time limit exceed.

OUTPUT DETAILS:

FR builds the three lifts. Using (1, 1) as the lower-left corner,

the lifts are (3, 1) <-> (8, 2), (7, 3) <-> (5, 2), and (1, 3) <->

(2, 2). All locations are now connected. For example, a cow wishing

to travel from (9, 1) to (2, 2) would ski (9, 1) -> (8, 1) -> (7,

1) -> (7, 2) -> (7, 3), take the lift from (7, 3) -> (5, 2), ski

(5, 2) -> (4, 2) -> (3, 2) -> (3, 3) -> (2, 3) -> (1, 3), and then

take the lift from (1, 3) - > (2, 2). There is no solution using

fewer than three lifts.

#include<stdio.h>
#include<string.h>
#include<stack>
#define INF 1000010
#define P 261010
using namespace std;
stack<int>S;
int a[550][550],map[P][10],low[P],dfn[P];
int instack[P];
int bnt,be[P],n,m;
int index,in[P],out[P];
void build(){
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++){
		if(a[i][j]>=a[i-1][j])map[j+m*i-m][++map[j+m*i-m][0]] = j+(i-2)*m;
	    if(a[i][j]>=a[i+1][j])map[j+m*i-m][++map[j+m*i-m][0]] = j+i*m;
	    if(a[i][j]>=a[i][j+1])map[j+m*i-m][++map[j+m*i-m][0]] = j+(i-1)*m+1;
	    if(a[i][j]>=a[i][j-1])map[j+m*i-m][++map[j+m*i-m][0]] = j+(i-1)*m-1;
	}
}
void tarjan(int i){
	dfn[i] = low[i] = ++index;
    S.push(i);
	instack[i] = 1;
	for(int j = 1;j<=map[i][0];j++){
		int k = map[i][j];
		if(!dfn[k]){
			tarjan(k);
			low[i] = min(low[i],low[k]);
		}
		else if(instack[k]){
		low[i] = min(low[i],dfn[k]);
		}
	}
	if(dfn[i]==low[i]){
		bnt++;
		int kk;
		do{
			kk = S.top();
			S.pop();
			instack[kk] = 0;
			be[kk] = bnt;
		}while(i!=kk);
	}
}
int main(){
	while(~scanf("%d%d",&m,&n)){
		int ans,ans1;
		memset(dfn,0,sizeof(dfn));
		memset(in,0,sizeof(in));
		memset(out,0,sizeof(out));
		memset(instack,0,sizeof(instack));
		bnt = ans = ans1 = index = 0;
		for(int i=0;i<=n+1;i++)a[i][0] = a[i][m+1] = INF;
		for(int j=0;j<=m+1;j++)a[0][j] = a[n+1][j] = INF;
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				scanf("%d",&a[i][j]);
		        map[j+(i-1)*m][0] = 0;
			}
		}
		build();
		for(int i=1;i<=n*m;i++)
		if(!dfn[i])
		tarjan(i);
		for(int i=1;i<=n*m;i++){
			for(int j =1;j<=map[i][0];j++)
			if(be[i]!=be[map[i][j]]){
			out[be[i]]++;
			in[be[map[i][j]]]++;
			}
		}
		for(int i=1;i<=bnt;i++){
				if(out[i]==0)ans++;
		        if(in[i]==0)ans1++;
		}
	    if(bnt==1)printf("0\n");
	    else printf("%d\n",max(ans,ans1));

	}
}
在POJ能过,在杭电就过不了,是什么原因啊,。。。。。。??!坑爹啊

tarjan + 缩点

时间: 2024-10-12 14:27:01

tarjan + 缩点的相关文章

【BZOJ-1924】所驼门王的宝藏 Tarjan缩点(+拓扑排序) + 拓扑图DP

1924: [Sdoi2010]所驼门王的宝藏 Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 787  Solved: 318[Submit][Status][Discuss] Description Input 第一行给出三个正整数 N, R, C. 以下 N 行,每行给出一扇传送门的信息,包含三个正整数xi, yi, Ti,表示该传送门设在位于第 xi行第yi列的藏宝宫室,类型为 Ti.Ti是一个1~3间的整数, 1表示可以传送到第 xi行任意

【BZOJ-1797】Mincut 最小割 最大流 + Tarjan + 缩点

1797: [Ahoi2009]Mincut 最小割 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1685  Solved: 724[Submit][Status][Discuss] Description A,B两个国家正在交战,其中A国的物资运输网中有N个中转站,M条单向道路.设其中第i (1≤i≤M)条道路连接了vi,ui两个中转站,那么中转站vi可以通过该道路到达ui中转站,如果切断这条道路,需要代价ci.现在B国想找出一个路径切断方案

[BZOJ 1051][HAOI 2006]受欢迎的牛(tarjan缩点)

http://www.lydsy.com:808/JudgeOnline/problem.php?id=1051 唔...这题好像在POJ上见过? 比较水的题,很好想出思路.牛和牛之间的关系就像有向图,牛a喜欢牛b相当于建立有向边a->b,然后在这个有向图中,每个强连通分量里的牛们相当于是相互喜欢的,把这个图缩点成DAG,DAG里如果有且仅有一个出度为0的点,则这个点对应强连通分量里的所有牛都是受欢迎的牛,如果没有出度为0的点,当然就没受欢迎的牛了,如果出度为0的点的个数大于1,则每个出度为0的

tarjan缩点以及链式前向星的基本+应用(洛谷1262 间谍网络)

题目描述 由于外国间谍的大量渗入,国家安全正处于高度的危机之中.如果A间谍手中掌握着关于B间谍的犯罪证据,则称A可以揭发B.有些间谍收受贿赂,只要给他们一定数量的美元,他们就愿意交出手中掌握的全部情报.所以,如果我们能够收买一些间谍的话,我们就可能控制间谍网中的每一分子.因为一旦我们逮捕了一个间谍,他手中掌握的情报都将归我们所有,这样就有可能逮捕新的间谍,掌握新的情报. 我们的反间谍机关提供了一份资料,色括所有已知的受贿的间谍,以及他们愿意收受的具体数额.同时我们还知道哪些间谍手中具体掌握了哪些

【BZOJ-2438】杀人游戏 Tarjan + 缩点 + 概率

2438: [中山市选2011]杀人游戏 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1638  Solved: 433[Submit][Status][Discuss] Description 一位冷血的杀手潜入 Na-wiat,并假装成平民.警察希望能在 N 个人里面,查出谁是杀手. 警察能够对每一个人进行查证,假如查证的对象是平民,他会告诉警察,他认识的人, 谁是杀手, 谁是平民. 假如查证的对象是杀手, 杀手将会把警察干掉. 现在警察掌

UVA11504- Dominos(Tarjan+缩点)

题目链接 题意:多米诺骨牌的游戏,给出一些牌,以及哪张牌倒了之后会推倒哪张牌,求最少的推倒牌的张数,使得所有牌都倒下去. 思路:有向图的强连通分量,用Tarjan缩点之后找出入度为0的点的个数,即为答案. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int MAXN = 100100;

UVA 11324.The Largest Clique tarjan缩点+拓扑dp

题目链接:https://vjudge.net/problem/UVA-11324 题意:求一个有向图中结点数最大的结点集,使得该结点集中任意两个结点u和v满足:要目u可以到达v,要么v可以到达u(相互可达也可以). 思路:同一个强联通分量中满足结点集中任意两个结点u和v满足:要目u可以到达v,要么v可以到达u(相互可达也可以).把强联通分量收缩点后得到scc图,让每个scc结点的权值等于他的结点数,则求scc图上权最大的路径.拓扑dp,也可以直接bfs,但是要建立一个新的起点,连接所有入度为0

UvaLive4287 roving Equivalences(Tarjan缩点+DAG)

UvaLive4287 roving Equivalences 题意:给n个定理,以及m个关系,即u定理可以推出v定理.问至少还需要加多少个条件,才能是定理两两互推. 思路:Tarjan缩点.然后变成一个DAG.ans1记录入度为0的联通块,ans2记录出度为0的联通块.输出较大值即可.注意如果点数为1或者只有一个强连通分量要输出0. /* ID: onlyazh1 LANG: C++ TASK: Knights of the Round Table */ #include<iostream>

强连通分量tarjan缩点——POJ2186 Popular Cows

这里的Tarjan是基于DFS,用于求有向图的强联通分量. 运用了一个点dfn时间戳和low的关系巧妙地判断出一个强联通分量,从而实现一次DFS即可求出所有的强联通分量. §有向图中, u可达v不一定意味着v可达u.    相互可达则属于同一个强连通分量    (Strongly Connected Component, SCC) §有向图和它的转置的强连通分量相同 §所有SCC构成一个DAG(有向无环图) dfn[u]为节点u搜索的次序编号(时间戳),即首次访问u的时间 low[u]为u或u的

P2341 [HAOI2006]受欢迎的牛(tarjan+缩点)

P2341 [HAOI2006]受欢迎的牛 题目描述 每头奶牛都梦想成为牛棚里的明星.被所有奶牛喜欢的奶牛就是一头明星奶牛.所有奶 牛都是自恋狂,每头奶牛总是喜欢自己的.奶牛之间的“喜欢”是可以传递的——如果A喜 欢B,B喜欢C,那么A也喜欢C.牛栏里共有N 头奶牛,给定一些奶牛之间的爱慕关系,请你 算出有多少头奶牛可以当明星. 输入输出格式 输入格式: ? 第一行:两个用空格分开的整数:N和M ? 第二行到第M + 1行:每行两个用空格分开的整数:A和B,表示A喜欢B 输出格式: ? 第一行: