• poj2375 强连通


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

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

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

    链式前向星:

      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<stack>
      4 #include<queue>
      5 using namespace std;
      6 
      7 const int maxn=250005;
      8 const int maxm=1e6+5;
      9 
     10 int head[maxn],point[maxm],nxt[maxm],size;
     11 int n,t,scccnt;
     12 int stx[maxn],low[maxn],scc[maxn];
     13 int id[maxn],od[maxn];
     14 int ma[505][505];
     15 int xx[4]={1,-1,0,0};
     16 int yy[4]={0,0,1,-1};
     17 stack<int>S;
     18 
     19 int max(int a,int b){return a>b?a:b;}
     20 
     21 void init(){
     22     memset(head,-1,sizeof(head));
     23     size=0;
     24 }
     25 
     26 void add(int a,int b){
     27     point[size]=b;
     28     nxt[size]=head[a];
     29     head[a]=size++;
     30 }
     31 
     32 void dfs(int s){
     33     stx[s]=low[s]=++t;
     34     S.push(s);
     35     for(int i=head[s];~i;i=nxt[i]){
     36         int j=point[i];
     37         if(!stx[j]){
     38             dfs(j);
     39             low[s]=min(low[s],low[j]);
     40         }
     41         else if(!scc[j]){
     42             low[s]=min(low[s],stx[j]);
     43         }
     44     }
     45     if(low[s]==stx[s]){
     46         scccnt++;
     47         while(1){
     48             int u=S.top();S.pop();
     49             scc[u]=scccnt;
     50             if(s==u)break;
     51         }
     52     }
     53 }
     54 
     55 void setscc(){
     56     memset(stx,0,sizeof(stx));
     57     memset(scc,0,sizeof(scc));
     58     t=scccnt=0;
     59     for(int i=1;i<=n;++i)if(!stx[i])dfs(i);
     60     for(int i=1;i<=n;++i){
     61         for(int j=head[i];~j;j=nxt[j]){
     62             int k=point[j];
     63             if(scc[i]!=scc[k]){
     64                 od[scc[i]]++;
     65                 id[scc[k]]++;
     66             }
     67         }
     68     }
     69 }
     70 
     71 int main(){
     72     int w,l;
     73     scanf("%d%d",&w,&l);
     74     n=w*l;
     75     init();
     76     for(int i=1;i<=l;++i){
     77         for(int j=1;j<=w;++j){
     78             scanf("%d",&ma[i][j]);
     79         }
     80     }
     81     for(int i=1;i<=l;++i){
     82         for(int j=1;j<=w;++j){
     83             for(int k=0;k<4;++k){
     84                 int x=i+xx[k],y=j+yy[k];
     85                 if(x>=1&&x<=l&&y>=1&&y<=w&&ma[x][y]<=ma[i][j]){
     86                     add((i-1)*w+j,(x-1)*w+y);
     87                 }
     88             }
     89         }
     90     }
     91     setscc();
     92     if(scccnt==1)printf("0
    ");
     93     else{
     94         int in=0,out=0;
     95         for(int i=1;i<=scccnt;++i){
     96             if(!id[i])in++;
     97             if(!od[i])out++;
     98         }
     99         printf("%d
    ",max(in,out));
    100     }
    101 }
    View Code

    邻接矩阵:

      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<stack>
      4 #include<queue>
      5 using namespace std;
      6 
      7 const int maxn=505*505;
      8 
      9 int n,t,scccnt;
     10 int w,l;
     11 int stx[maxn],low[maxn],scc[maxn];
     12 int id[maxn],od[maxn];
     13 int ma[505][505];
     14 int xx[4]={1,-1,0,0};
     15 int yy[4]={0,0,1,-1};
     16 stack<int>S;
     17 
     18 int max(int a,int b){return a>b?a:b;}
     19 
     20 inline int getid(int a,int b){
     21     return (a-1)*w+b;
     22 }
     23 
     24 inline void getpoint(int num,int &a,int &b){
     25     a=num/w;
     26     b=num%w;
     27     if(b)a++;
     28     else b=w;
     29 }
     30 
     31 void dfs(int s){
     32     stx[s]=low[s]=++t;
     33     S.push(s);
     34     int x,y;
     35     getpoint(s,x,y);
     36     for(int p=0;p<4;++p){
     37         int dx=x+xx[p],dy=y+yy[p];
     38         if(dx>=1&&dx<=l&&dy>=1&&dy<=w&&ma[dx][dy]<=ma[x][y]){
     39             int j=getid(dx,dy);
     40             if(!stx[j]){
     41                 dfs(j);
     42                 low[s]=min(low[s],low[j]);
     43             }
     44             else if(!scc[j]){
     45                 low[s]=min(low[s],stx[j]);
     46             }
     47         }
     48     }
     49     if(low[s]==stx[s]){
     50         scccnt++;
     51         while(1){
     52             int u=S.top();S.pop();
     53             scc[u]=scccnt;
     54             if(s==u)break;
     55         }
     56     }
     57 }
     58 
     59 void setscc(){
     60     memset(stx,0,sizeof(stx));
     61     memset(scc,0,sizeof(scc));
     62     t=scccnt=0;
     63     for(int i=1;i<=n;++i)if(!stx[i])dfs(i);
     64     for(int i=1;i<=n;++i){
     65         int x,y;
     66         getpoint(i,x,y);
     67         for(int p=0;p<4;++p){
     68             int dx=x+xx[p],dy=y+yy[p];
     69             if(dx>=1&&dx<=l&&dy>=1&&dy<=w&&ma[dx][dy]<=ma[x][y]){
     70                 int k=getid(dx,dy);
     71                 if(scc[i]!=scc[k]){
     72                     od[scc[i]]++;
     73                     id[scc[k]]++;
     74                 }
     75             }
     76         }
     77     }
     78 }
     79 
     80 int main(){
     81     scanf("%d%d",&w,&l);
     82     n=w*l;
     83     memset(id,0,sizeof(id));
     84     memset(od,0,sizeof(od));
     85     for(int i=1;i<=l;++i){
     86         for(int j=1;j<=w;++j){
     87             scanf("%d",&ma[i][j]);
     88         }
     89     }
     90     setscc();
     91     if(scccnt==1)printf("0
    ");
     92     else{
     93         int in=0,out=0;
     94         for(int i=1;i<=scccnt;++i){
     95             if(!id[i])in++;
     96             if(!od[i])out++;
     97         }
     98         printf("%d
    ",max(in,out));
     99     }
    100 }
    View Code
  • 相关阅读:
    生成实用包装码
    区分排序函数
    mysql优化
    高并发、大流量、大存储
    数据库的搬移
    linux查看系统日志及具体服务日志
    springboot拦截器实现
    使用ajax的get请求渲染html
    百度echarts折线图使用示例
    前端特殊符号转码
  • 原文地址:https://www.cnblogs.com/cenariusxz/p/4816217.html
Copyright © 2020-2023  润新知