poj2375 强连通
题意:有一个 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 强连通的更多相关文章
- POJ2375 Cow Ski Area (强连通)(缩点)
Cow Ski Area Time Limit: 1000MS Memory Limit: 65536K Total Sub ...
- HDU5934 强连通分量
题目:http://acm.hdu.edu.cn/showproblem.php?pid=5934 根据距离关系建边 对于强连通分量来说,只需引爆话费最小的炸弹即可引爆整个强连通分量 将所有的强连通分 ...
- POJ1236Network of Schools[强连通分量|缩点]
Network of Schools Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 16571 Accepted: 65 ...
- 有向图的强连通分量的求解算法Tarjan
Tarjan算法 Tarjan算法是基于dfs算法,每一个强连通分量为搜索树中的一颗子树.搜索时,把当前搜索树中的未处理的结点加入一个栈中,回溯时可以判断栈顶到栈中的结点是不是在同一个强连通分量中.当 ...
- The Bottom of a Graph-POJ2553强连通
The Bottom of a Graph Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 9759 Accepted: 4053 ...
- Tarjan算法--强连通分量
tarjan的过程就是dfs过程. 图一般能画成树,树的边有三种类型,树枝边 + 横叉边(两点没有父子关系) + 后向边(两点之间有父子关系): 可以看到只有后向边能构成环,即只有第三张图是强连通分量 ...
- bzoj 1051 (强连通) 受欢迎的牛
题目:这里 题意: Description 每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎. 这 种关系是具有传递性的,如果A认为B受欢迎,B认为 ...
- 强连通分量的一二三 | | JZOJ【P1232】 | | 我也不知道我写的什么
贴题: 在幻想乡,上白泽慧音是以知识渊博闻名的老师.春雪异变导致人间之里的很多道路都被大雪堵塞,使有的学生不能顺利地到达慧音所在的村庄.因此慧音决定换一个能够聚集最多人数的村庄作为新的教学地点.人间之 ...
- 有向图强连通分量的Tarjan算法
有向图强连通分量的Tarjan算法 [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G ...
随机推荐
- 后台框架--HUI 的学习跟使用1
下载跟查看说明文档:官方 https://github.com/jackying/ 官网:http://www.h-ui.net/H-ui.admin.shtml 后台,http://www.h-ui ...
- ASIHTTPRequest 在release(打包)模式下数据获取或post失败问题
ASIHTTPRequest 在relase模式下失效 表现为,调用网络请求后没有任何反应 原因之一: ARC模式下,在ASIHTTPRequest 前面会加上__weak来解决循环应用,这个__we ...
- 大开眼界 游览Facebook香港办公室
想加入Facebook 的话不一定要跑去美国,Facebook在香港也开了一个很赞的办公室.除了无敌海景外,更可享用按摩椅.乒乓球桌.跑步机.麻将桌.酒廊.育婴室及开放式厨房.
- SharePoint 2013 开发——SharePoint APP介绍
博客地址:http://blog.csdn.net/FoxDave 新的APP模型让我们能够创建看起来像是SharePoint的一部分的应用程序,但是它完全运行在独立于SharePoint服务器 ...
- iOS网页开发技术总结
网页组成 一个有具体功能的完整的网页,一般由3部分组成 HTML:网页的具体内容和结构 CSS:网页的样式(美化网页最重要的一块) JavaScript:网页的交互效果,比如对用户鼠标事件做出响应 H ...
- 一道面试题,简单模拟spring ioc
自己实现的,程序写的土了点,很多情况没去考虑,主要是复习理解怎么使用反射来实现spring 的依赖注入. package dom4jtest; import java.lang.reflect.Inv ...
- MySQL表的增删改查和列的修改(二)
一.使用Like模糊查找搜索前缀为以“exam_”开头的表名 show tables like 'exam_%' ; 语句结束符号是:也是用\G来表示 二.MySQL表的CRUD 2.1 创建表: C ...
- opencv中的Mat类型
Mat类型主要是跟matlab中的数据类型一样.故用起来很方便. Mat最大的优势跟STL很相似,都是对内存进行动态的管理,不需要之前用户手动的管理内存,对于一些大型的开发,有时候投入的lpImage ...
- EF 学习笔记
1.EFcodeFirst如何使用存储过程!public string GetCoupon(int type) { using (var db=new ProbabilityContext()) { ...
- SVG 2D入门5 - 颜色的表示
SVG和canvas中是一样的,都是使用标准的HTML/CSS中的颜色表示方法,这些颜色都可以用于fill和stroke属性.基本有下面这些定义颜色的方式:1. 颜色名字: 直接使用颜色名字red, ...