poj 3694 Network

题意: 添加每条新连接后网络中桥的数目
// 超时 先放着了 ,下次改
//早上这代码超时了 下午改了,代码在下面
#include <iostream> #include <algorithm> #include <queue> #include <stack> #include <math.h> #include <stdio.h> #include <string.h> using namespace std; #define MOD 1000000007 #define maxn 440000 #define maxm 100010 struct Edge{ int to; int num; int next; Edge(){}; Edge(int u,int v){to=u;next=v;} }E[maxn]; int V[maxm],num; bool tag[maxn]; int pre[maxm]; int dfst,bcc; int ans,eg; void init(int n){ eg=0; dfst=0; num=0; bcc=0; for(int i=1;i<=n;i++) V[i]=-1; } void add(int u,int v){ // 坑爹 原来原图没有重边的 郁闷 ,这里就耗了不少时间
int e; for(e=V[u];e!=-1;e=E[e].next) { if(v==E[e].to){ tag[E[e].num]=1;return; } } eg++; E[num].to=v; E[num].num=eg; E[num].next=V[u]; V[u]=num++; E[num].to=u; E[num].num=eg; E[num].next=V[v]; V[v]=num++; } int dfs(int u,int fa){ int lowu; lowu=pre[u]=++dfst; int v,e; for(e=V[u];e!=-1;e=E[e].next){ v=E[e].to; if(!pre[v]){ int lowv=dfs(v,u); lowu=min(lowu,lowv); if(lowv>pre[u]&&!tag[E[e].num]){ ans++; } } else if(v!=fa) lowu=min(lowu,pre[v]); } return lowu; } int main() { int n,m,Q; int u,v; int i,j=1; while(scanf("%d %d",&n,&m),n|m){ init(n); for(i=1;i<=m;i++){ scanf("%d %d",&u,&v); tag[i]=0; add(u,v); } printf("Case %d:\n",j++); scanf("%d",&Q); for(i=1;i<=Q;i++) tag[i+m]=0; while(Q--){ scanf("%d %d",&u,&v); add(u,v); for(i=1;i<=n;i++) pre[i]=0; ans=0; dfst=0; dfs(1,0); printf("%d\n",ans); } printf("\n"); } return 0; }

// 在原来的基础上 执行一次dfs 然就找两点的lca 我不愿去缩点 啥的, 网上看到一个不错的,就用了
// 就是先让 x,y达到同一深度 然后回走 直到碰面 边上遇到桥就标记删除
#include <iostream>

#include <algorithm>

#include <queue>

#include <stack>

#include <math.h>

#include <stdio.h>

#include <string.h>

using namespace std;

#define MOD 1000000007

#define maxn 440000

#define maxm 100010

struct Edge{

    int to;

  //  int num;

    int next;

    Edge(){};

    Edge(int u,int v){to=u;next=v;}

}E[maxn];

int V[maxm],num;

bool tag[maxm];

int fa[maxm];

int pre[maxm],low;

int dfst;

int ans;

void init(int n){

    dfst=0;

    num=0;

    ans=0;

    for(int i=1;i<=n;i++){

        V[i]=-1;

        pre[i]=0;

        tag[i]=0;

    }

}

void add(int u,int v){

    E[num].to=v;

   // E[num].num=m;

    E[num].next=V[u];

    V[u]=num++;



    E[num].to=u;

  //  E[num].num=m;

    E[num].next=V[v];

    V[v]=num++;

}

int dfs(int u,int dp){

   int lowu=pre[u]=dp;

   int v,e;

   for(e=V[u];e!=-1;e=E[e].next){

        v=E[e].to;

          if(!pre[v]){

            fa[v]=u;

          //  printf("?%d %d %d\n",v,u,fa[v]);

            int lowv=dfs(v,dp+1);

            lowu=min(lowu,lowv);

            if(lowv>pre[u]){

               ans++;

               tag[v]=true; //printf("%d",v);

            }

          }

          else if(v!=fa[u]) lowu=min(lowu,pre[v]);

   }

  // printf("%d %d ",u,fa[u]);

   return lowu;

}

void lca(int x,int y){

    if(pre[x]>pre[y]) swap(x,y);

    while(pre[y]!=pre[x]){

        if(tag[y]){ans--;tag[y]=false;}

        y=fa[y];

    }

    while(x!=y){

         if(tag[x]){ans--;tag[x]=false;}

         if(tag[y]){ans--;tag[y]=false;}

         x=fa[x];y=fa[y];

    }

}

int main()

{

    int n,m,Q;

    int u,v;

    int i,j=1;

    while(scanf("%d %d",&n,&m),n|m){

        init(n);

        for(i=1;i<=m;i++){

            scanf("%d %d",&u,&v);

            add(u,v);

        }

        fa[1]=1;

        dfs(1,1);

        printf("Case %d:\n",j++);

        scanf("%d",&Q);// for(i=1;i<=Q;i++) tag[i+m]=0;

        while(Q--){

          scanf("%d %d",&u,&v);

          lca(u,v);

          printf("%d\n",ans);

        }

        printf("\n");

    }

    return 0;

}
 

 

你可能感兴趣的:(NetWork)