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 ...
随机推荐
- PHP笔记(一)
1. public 表示全局,类内部外部子类都可以访问:private表示私有的,只有本类内部可以使用:protected表示受保护的,只有本类或子类或父类中可以访问: 2. ==是包括变量值与类型完 ...
- Android之View.onMeasure方法
View在屏幕上显示出来要先经过measure(计算)和layout(布局). 1.什么时候调用onMeasure方法? 当控件的父元素正要放置该控件时调用.父元素会问子控件一个问题,“你想要用多大地 ...
- php的数组与数据结构
一.数组的分类与定义 分类: 1.索引数组 $array = array(1,2,3,4,5); 2.关联数组 $array=array(1=>"aa","bb ...
- 一篇介绍jquery中的ajax的结合
<script type="text/javascript"> function Text_ajax() { $.aja ...
- 高效的iOS宏定义
iOS开发过程中使用一些常用的宏可以提高开发效率,提高代码的重用性:将这些宏放到一个头文件里然后再放到工程中的-Prefix.pch文件中(或者直接放到-Prefix.pch中)直接可以使用,灰常方便 ...
- .NET项目框架(转)
摘要:本文描述了在用VS.NET进行B/S开发时采用的框架结构,一般建立类库项目和Web项目,在Web基本aspx页面类中调用类库中方法,同时在aspx页面类中不需要写任何对数据库操作的SQL代码,便 ...
- php大力力 [005节] php大力力简单计算器001
2015-08-22 php大力力005. php大力力简单计算器001: 上网看视频,看了半天,敲击代码,如下: <html> <head> <title>简单计 ...
- BZOJ 3181 BROJ
像我这种SB还是早点退役. #include<iostream> #include<cstdio> #include<cstring> #include<al ...
- Include and Require
The include or require statement takes all the text/codde/markup that exists in the specified file a ...
- APNS IOS PHP 苹果推送
IOS---APNS 消息推送实践 首先,需要一个pem的证书,该证书需要与开发时签名用的一致. 具体生成pem证书方法如下: 1. 登录到 iPhone Developer Connection P ...