求桥,割点(HihoCoder - 1183 )

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

struct my{
   int v;
   int next;
};
struct dage{
  int u;
  int v;
};

dage gebian[1000000*2+10];
int topbian;
bool  iscut[200000+10];
int adj[200000+10];
my bian[2000000+10];
int  pre[200000+10];
int dfsnum;
int n,m,fa;

void myinsert(int u,int v){
     bian[++fa].v=v;
     bian[fa].next=adj[u];;
     adj[u]=fa;
}

bool cmp(const dage &x,const dage &y){
     if(x.u==y.u) return x.v<=y.v;
     else return x.u<=y.u;
}
int tarjan(int u,int fa1){
    int lowu=pre[u]=++dfsnum;
    int child=0;
    for (int i=adj[u];i!=-1;i=bian[i].next){
        int v=bian[i].v;
        if(!pre[v]){
        child++;
        int lowv=tarjan(v,u);
        lowu=min(lowv,lowu);
        if(lowv>pre[u]){
                if(u<v){
            gebian[++topbian].u=u;
            gebian[topbian].v=v;
                }
            else {
                gebian[++topbian].u=v;
            gebian[topbian].v=u;
            }
        }
        if(lowv>=pre[u]){
            iscut[u]=true;
          }
        }
        else if(pre[v]<pre[u]&&v!=fa1){
            lowu=min(pre[v],lowu);
        }
    }
    if(fa1<0&&child==1) iscut[u]=false;
    return lowu;
}
int main(){
   memset(adj,-1,sizeof(adj));
   memset(bian,-1,sizeof(bian));
   scanf("%d%d",&n,&m);
   int u,v;
   for (int i=1;i<=m;i++){
    scanf("%d%d",&u,&v);
    myinsert(u,v);
    myinsert(v,u);
   }
   tarjan(1,-1);
   int sum=0;
 for (int i=1;i<=n;i++)
    if(iscut[i]) {
            sum++;
            printf("%d ",i);
    }
    //printf("\n");
  if(sum==0) printf("Null\n");
  else printf("\n");
   sort(gebian+1,gebian+1+topbian,cmp);
   for (int i=1;i<=topbian;i++) {
        printf("%d %d\n",gebian[i].u,gebian[i].v);
   }
return 0;
}

posted @ 2018-01-04 19:29  lmjer  阅读(138)  评论(0编辑  收藏  举报