zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    nconf修改密码
    快速清空一个文
    freebsd安装snmp
    -bash: mail: command not found
    重置Cacti密码
    cacti添加被监控机全过程
    cacti图形字符乱码
    博客链接
    tar命令详解
    MainPresenter 实现类
  • 原文地址:https://www.cnblogs.com/cenariusxz/p/4816217.html
Copyright © 2011-2022 走看看