POJ 2375 Cow Ski Area (强连通分量)

题目地址:POJ 2375

对每一个点向与之相邻并h小于该点的点加有向边。

然后强连通缩点。问题就转化成了最少加几条边使得图为强连通图,取入度为0和出度为0的点数的较大者就可以。注意,当强连通分量仅仅有一个的时候。答案是0,而不是1.

代码例如以下:

#include <iostream>
#include <string.h>
#include <math.h>
#include <queue>
#include <algorithm>
#include <stdlib.h>
#include <map>
#include <set>
#include <stdio.h>
using namespace std;
#define LL long long
#define pi acos(-1.0)
const int mod=1e9+7;
const int INF=0x3f3f3f3f;
const double eqs=1e-9;
const int MAXN=250000+10;
int head[MAXN], Ecnt, top, indx, scc;
int low[MAXN], dfn[MAXN], belong[MAXN], instack[MAXN], stk[MAXN], out[MAXN], in[MAXN];
int mp[600][600];
int jx[]={0,0,1,-1};
int jy[]={1,-1,0,0};
struct node
{
        int u, v, next;
}edge[1000000];
void add(int u, int v)
{
        edge[Ecnt].v=v;
        edge[Ecnt].next=head[u];
        head[u]=Ecnt++;
}
void tarjan(int u)
{
        low[u]=dfn[u]=++indx;
        instack[u]=1;
        stk[++top]=u;
        for(int i=head[u];i!=-1;i=edge[i].next){
                int v=edge[i].v;
                if(!dfn[v]){
                        tarjan(v);
                        low[u]=min(low[u],low[v]);
                }
                else if(instack[v]){
                        low[u]=min(low[u],dfn[v]);
                }
        }
        if(low[u]==dfn[u]){
                scc++;
                while(1){
                        int v=stk[top--];
                        belong[v]=scc;
                        instack[v]=0;
                        if(u==v) break;
                }
        }
}
void init()
{
        memset(head,-1,sizeof(head));
        memset(dfn,0,sizeof(dfn));
        memset(instack,0,sizeof(instack));
        memset(in,0,sizeof(in));
        memset(out,0,sizeof(out));
        Ecnt=top=indx=scc=0;
}
int main()
{
        int n, m, i, j, k, a, b, cntin, cntout;
        init();
        scanf("%d%d",&n,&m);
        for(i=0;i<m;i++){
                for(j=0;j<n;j++){
                        scanf("%d",&mp[i][j]);
                }
        }
        for(i=0;i<m;i++){
                for(j=0;j<n;j++){
                        for(k=0;k<4;k++){
                                a=i+jx[k];
                                b=j+jy[k];
                                if(a>=0&&a<m&&b>=0&&b<n&&mp[a][b]<=mp[i][j]){
                                        add(i*n+j,a*n+b);
                                }
                        }
                }
        }
        for(i=0;i<n*m;i++){
                if(!dfn[i])
                        tarjan(i);
        }
        if(scc==1){
                printf("0\n");
                return 0;
        }
        for(i=0;i<n*m;i++){
                for(j=head[i];j!=-1;j=edge[j].next){
                        int v=edge[j].v;
                        if(belong[i]!=belong[v]){
                                out[belong[i]]++;
                                in[belong[v]]++;
                        }
                }
        }
        cntin=cntout=0;
        for(i=1;i<=scc;i++){
                if(!in[i]) cntin++;
                if(!out[i]) cntout++;
        }
        printf("%d\n",max(cntin,cntout));
        return 0;
}
时间: 2024-11-08 16:10:13

POJ 2375 Cow Ski Area (强连通分量)的相关文章

POJ 2375 Cow Ski Area(强连通)

POJ 2375 Cow Ski Area 题目链接 题意:给定一个滑雪场,每个点能向周围4个点高度小于等于这个点的点滑,现在要建电缆,使得任意两点都有路径互相可达,问最少需要几条电缆 思路:强连通缩点,每个点就是一个点,能走的建边,缩点后找入度出度为0的个数的最大值就是答案,注意一开始就强连通了答案应该是0 代码: #include <cstdio> #include <cstring> #include <stack> #include <algorithm&

POJ 2375 Cow Ski Area【tarjan】

题目大意:一个W*L的山,每个山有个高度,当且仅当一个山不比它相邻(有公共边的格子)的山矮时能够滑过去,现在可以装化学电梯来无视山的高度滑雪,问最少装多少电梯使得任意两点都可到达 思路:最后一句话已经把强连通模型裸裸地说出来了 那问题变成了一个图最小加几条边变成强连通图的经典问题,比较一下出度为0和入度为0的点的个数的大小即可,还有个特例只有一个SCC的情况 #include<cstdio> #include<string.h> #include<iostream> #

POJ2375 Cow Ski Area 【强连通分量】+【DFS】

Cow Ski Area Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2323   Accepted: 660 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 some

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

Cow Ski Area Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3323   Accepted: 919 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 some

Poj 1904 King&#39;s Quest 强连通分量

题目链接: http://poj.org/problem?id=1904 题意: 有n个王子和n个公主,王子只能娶自己心仪的公主(一个王子可能会有多个心仪的公主),现已给出一个完美匹配,问每个王子都可以取哪些公主,并且保证取了一个公主后,全局还是存在完美匹配. 题解: 1.建图: 如果王子u对公主v心仪,则连一条边u->v.在样例给出的那组完美匹配中,如果王子u娶了公主v,连一条边v->u. 2.求强连通分量: 如果王子和自己心仪的公主属于同一个强连通分量,那么王子就可以娶这个公主. 1 #i

POJ - 1904 King&#39;s Quest(强连通分量+二分图匹配)

题目大意:有N个帅哥和N个美女,现在给出每个帅哥所喜欢的美女的编号,和一个帅哥和美女的完美匹配 问每个帅哥可以娶多少个美女,且当他娶完这个美女后,剩下的人还可以完美匹配 解题思路:神题啊,给一个大神的详细解答 具体是这样的,首先先建边,把帅哥和能娶到的美女连边,再把完美匹配的美女和帅哥连边,这样就形成了一张有向图了 接着,找出这张有向图的所有强连通分量,在强连通分量里面的帅哥都可以娶到自己喜欢的美女,且娶完这个美女后,不会影响到其他人 为什么呢? 假设xi为帅哥,yi和yj为美女,假设给定的完美

POJ 1904 King&#39;s Quest 强连通分量+二分图增广判定

http://www.cnblogs.com/zxndgv/archive/2011/08/06/2129333.html 这位神说的很好 #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <string> #include <stack> #include <ve

POJ 1904 King&#39;s Quest强连通分量+二分图完美匹配

题目描述: Description Once upon a time there lived a king and he had N sons. And there were N beautiful girls in the kingdom and the king knew about each of his sons which of those girls he did like. The sons of the king were young and light-headed, so i

POJ2375 Cow Ski Area【Tarjan】【强连通分量】

题目链接: http://poj.org/problem?id=2375 题目大意: 有一片供奶牛滑雪的滑雪场,可供滑雪的区域是W(宽)*L(长)的矩阵.上边有W*L个点.规定 奶牛从一个点只能向它上.下.左.右相邻的并且高度不大于它的点运动.现在想要在某些 点对之间架设缆车,使得奶牛可以从较低的地方想较高的地方运动,那么问题来了:最少需 要多少辆这样的缆车就可以使奶牛从每个点运动到可供滑雪区域的每个角落. 思路: 把奶牛符合从点u移动到点v的条件当做一条单向边.那么所有点和边就可以构成有向图.