题意:有一个 l * w 大小的滑雪场,每个格子都有一个高度,每个格子可以直接通到上下左右四个格子中高度小于等于自己的格子,现在要建立通道,能够连通任意两个格子,问最少建多少通道能够使所有格子能够互相到达。

其实就是问加多少条边能够使整个图强连通,也就是求强连通分量中入度为 0 和出度为 0 的分量个数的最大值,如果仅一个强连通分量则为 0 。

RE 10 发,我以为是因为我链式前向星数组开太大,于是换邻接矩阵,又 RE,一看DISCUSS,G++RE,C++AC,一交C++A了,把第一次RE的交了一发A了,所以RE的小伙伴们……交C++吧……

链式前向星:

 #include<stdio.h>
#include<string.h>
#include<stack>
#include<queue>
using namespace std; const int maxn=;
const int maxm=1e6+; int head[maxn],point[maxm],nxt[maxm],size;
int n,t,scccnt;
int stx[maxn],low[maxn],scc[maxn];
int id[maxn],od[maxn];
int ma[][];
int xx[]={,-,,};
int yy[]={,,,-};
stack<int>S; int max(int a,int b){return a>b?a:b;} void init(){
memset(head,-,sizeof(head));
size=;
} void add(int a,int b){
point[size]=b;
nxt[size]=head[a];
head[a]=size++;
} void dfs(int s){
stx[s]=low[s]=++t;
S.push(s);
for(int i=head[s];~i;i=nxt[i]){
int j=point[i];
if(!stx[j]){
dfs(j);
low[s]=min(low[s],low[j]);
}
else if(!scc[j]){
low[s]=min(low[s],stx[j]);
}
}
if(low[s]==stx[s]){
scccnt++;
while(){
int u=S.top();S.pop();
scc[u]=scccnt;
if(s==u)break;
}
}
} void setscc(){
memset(stx,,sizeof(stx));
memset(scc,,sizeof(scc));
t=scccnt=;
for(int i=;i<=n;++i)if(!stx[i])dfs(i);
for(int i=;i<=n;++i){
for(int j=head[i];~j;j=nxt[j]){
int k=point[j];
if(scc[i]!=scc[k]){
od[scc[i]]++;
id[scc[k]]++;
}
}
}
} int main(){
int w,l;
scanf("%d%d",&w,&l);
n=w*l;
init();
for(int i=;i<=l;++i){
for(int j=;j<=w;++j){
scanf("%d",&ma[i][j]);
}
}
for(int i=;i<=l;++i){
for(int j=;j<=w;++j){
for(int k=;k<;++k){
int x=i+xx[k],y=j+yy[k];
if(x>=&&x<=l&&y>=&&y<=w&&ma[x][y]<=ma[i][j]){
add((i-)*w+j,(x-)*w+y);
}
}
}
}
setscc();
if(scccnt==)printf("0\n");
else{
int in=,out=;
for(int i=;i<=scccnt;++i){
if(!id[i])in++;
if(!od[i])out++;
}
printf("%d\n",max(in,out));
}
}

邻接矩阵:

 #include<stdio.h>
#include<string.h>
#include<stack>
#include<queue>
using namespace std; const int maxn=*; int n,t,scccnt;
int w,l;
int stx[maxn],low[maxn],scc[maxn];
int id[maxn],od[maxn];
int ma[][];
int xx[]={,-,,};
int yy[]={,,,-};
stack<int>S; int max(int a,int b){return a>b?a:b;} inline int getid(int a,int b){
return (a-)*w+b;
} inline void getpoint(int num,int &a,int &b){
a=num/w;
b=num%w;
if(b)a++;
else b=w;
} void dfs(int s){
stx[s]=low[s]=++t;
S.push(s);
int x,y;
getpoint(s,x,y);
for(int p=;p<;++p){
int dx=x+xx[p],dy=y+yy[p];
if(dx>=&&dx<=l&&dy>=&&dy<=w&&ma[dx][dy]<=ma[x][y]){
int j=getid(dx,dy);
if(!stx[j]){
dfs(j);
low[s]=min(low[s],low[j]);
}
else if(!scc[j]){
low[s]=min(low[s],stx[j]);
}
}
}
if(low[s]==stx[s]){
scccnt++;
while(){
int u=S.top();S.pop();
scc[u]=scccnt;
if(s==u)break;
}
}
} void setscc(){
memset(stx,,sizeof(stx));
memset(scc,,sizeof(scc));
t=scccnt=;
for(int i=;i<=n;++i)if(!stx[i])dfs(i);
for(int i=;i<=n;++i){
int x,y;
getpoint(i,x,y);
for(int p=;p<;++p){
int dx=x+xx[p],dy=y+yy[p];
if(dx>=&&dx<=l&&dy>=&&dy<=w&&ma[dx][dy]<=ma[x][y]){
int k=getid(dx,dy);
if(scc[i]!=scc[k]){
od[scc[i]]++;
id[scc[k]]++;
}
}
}
}
} int main(){
scanf("%d%d",&w,&l);
n=w*l;
memset(id,,sizeof(id));
memset(od,,sizeof(od));
for(int i=;i<=l;++i){
for(int j=;j<=w;++j){
scanf("%d",&ma[i][j]);
}
}
setscc();
if(scccnt==)printf("0\n");
else{
int in=,out=;
for(int i=;i<=scccnt;++i){
if(!id[i])in++;
if(!od[i])out++;
}
printf("%d\n",max(in,out));
}
}

poj2375 强连通的更多相关文章

  1. POJ2375 Cow Ski Area (强连通)(缩点)

                                        Cow Ski Area Time Limit: 1000MS   Memory Limit: 65536K Total Sub ...

  2. HDU5934 强连通分量

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5934 根据距离关系建边 对于强连通分量来说,只需引爆话费最小的炸弹即可引爆整个强连通分量 将所有的强连通分 ...

  3. POJ1236Network of Schools[强连通分量|缩点]

    Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 16571   Accepted: 65 ...

  4. 有向图的强连通分量的求解算法Tarjan

    Tarjan算法 Tarjan算法是基于dfs算法,每一个强连通分量为搜索树中的一颗子树.搜索时,把当前搜索树中的未处理的结点加入一个栈中,回溯时可以判断栈顶到栈中的结点是不是在同一个强连通分量中.当 ...

  5. The Bottom of a Graph-POJ2553强连通

    The Bottom of a Graph Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 9759 Accepted: 4053 ...

  6. Tarjan算法--强连通分量

    tarjan的过程就是dfs过程. 图一般能画成树,树的边有三种类型,树枝边 + 横叉边(两点没有父子关系) + 后向边(两点之间有父子关系): 可以看到只有后向边能构成环,即只有第三张图是强连通分量 ...

  7. bzoj 1051 (强连通) 受欢迎的牛

    题目:这里 题意: Description 每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎. 这 种关系是具有传递性的,如果A认为B受欢迎,B认为 ...

  8. 强连通分量的一二三 | | JZOJ【P1232】 | | 我也不知道我写的什么

    贴题: 在幻想乡,上白泽慧音是以知识渊博闻名的老师.春雪异变导致人间之里的很多道路都被大雪堵塞,使有的学生不能顺利地到达慧音所在的村庄.因此慧音决定换一个能够聚集最多人数的村庄作为新的教学地点.人间之 ...

  9. 有向图强连通分量的Tarjan算法

    有向图强连通分量的Tarjan算法 [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G ...

随机推荐

  1. English idioms

    a hot potato : speak of an issue(mostly current) which many people are talking about and which is us ...

  2. Word2013可以写博客

    步骤如下http://www.cnblogs.com/guyichang/p/4629211.html

  3. JVM-JDK命令行工具

    JDK命令行工具 当我们进入JDK的安装目录里面的/bin目录,会发现有很多小工具,有我们熟悉的也经常用的java,javac,也有很多我们不怎么用到很陌生的工具.下面看看哪些平时不怎么用到的工具吧. ...

  4. 一道面试题,简单模拟spring ioc

    自己实现的,程序写的土了点,很多情况没去考虑,主要是复习理解怎么使用反射来实现spring 的依赖注入. package dom4jtest; import java.lang.reflect.Inv ...

  5. MapReduce实现TopK的示例

    由于开始学习MapReduce编程已经有一段时间了,作为一个从编程中寻找自信和乐趣以及热爱编程的孩子来讲,手开始变得很“痒”了,很想小试一下身手.于是自己编写了TopK的代码.TopK的意思就是从原文 ...

  6. HDU 3829 - Cat VS Dog (二分图最大独立集)

    题意:动物园有n只猫和m条狗,现在有p个小孩,他们有的喜欢猫,有的喜欢狗,其中喜欢猫的一定不喜欢狗,喜欢狗的一定不喜欢猫.现在管理员要从动物园中移除一些动物,如果一个小孩喜欢的动物留了下来而不喜欢的动 ...

  7. 配置navigation bar外观

    /* 配置navigation bar外观开始 */ self.navigationBar.translucent = YES; self.navigationBar.titleTextAttribu ...

  8. Connection to http://www.google.com:80 refused

    使用SDK Manager更新时出现问题 Failed to fetch URL https://dl-ssl.google.com/android/repository/repository-6.x ...

  9. android application plugins framework

    android插件式开发 android application plugins framework http://code.google.com/p/android-application-plug ...

  10. 2016-1-8 Quartz框架的学习,多个气球上升的小动画

    // // BallonView.m // 气球上升的动画 // // Created by Mac on 16/1/8. // Copyright © 2016年 Mac. All rights r ...