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;
}
 

 

posted on 2013-07-22 11:03  江财小子  阅读(154)  评论(0编辑  收藏  举报