POJ 3694 Network

12:

   着实写了好久 ,虽然一直照着别人的思路,一直TLE 

   思路:这题求无向图的桥

           用targan求桥时有这样一个性质 low[v]<dfn[u] 时 u是割点 那么 u-v这条边是桥。

证明:在

图论算法理论、实现及应用

 

王桂平、王 衍、任嘉辰 编著

420 面有证明 

       

后面利用LCA 暴力即可 因为询问次数不多 。

LCA (u,v)若两者在同一个缩点里面的话桥数不变。

否则 两者的缩点里面的桥都没有了

   1 #include<cstdio>

  2 #include<iostream>
  3 #include<vector>
  4 #include<stack>
  5 #include<algorithm>
  6 #include<string.h>
  7 
  8 using namespace std;
  9 
 10 #define N 100100
 11 #define M 200100
 12 
 13 int dfn[N],low[N],is_bridge[N],dfs_clock;
 14 int fa[N];
 15 int vis[N];
 16 int head[N];
 17 struct Edge{
 18        int v,next;
 19 }edge[M*2];
 20 
 21 int ans,cnt;
 22 int n,m;
 23 
 24 void dfs(int u,int f)
 25 {
 26     dfn[u]=low[u]=++dfs_clock;
 27     //  vis[u]=1;
 28     // fa[u]=f;
 29     for (int i=head[u];i!=-1;i=edge[i].next)
 30     {
 31         int v=edge[i].v;;
 32         if (v==f) continue;
 33        // fa[v]=u;
 34         if (dfn[v]==-1)
 35         {
 36             fa[v]=u;//因为这个位置TL很多次
 37             dfs(v,u);
 38             low[u]=min(low[u],low[v]);
 39             if (low[v]>dfn[u])
 40             {
 41                 ans++;
 42                 is_bridge[v]=1;
 43             }
 44         }
 45         else low[u]=min(low[u],dfn[v]);
 46     }
 47 }
 48 
 49 void  LCA(int u,int v)
 50 {
 51     if (dfn[u]>dfn[v]) swap(u,v);
 52     while (dfn[u]<dfn[v])
 53     {
 54         if (is_bridge[v])
 55         {
 56             ans--;
 57             is_bridge[v]=0;
 58         }
 59         v=fa[v];
 60     }
 61     while (u!=v)
 62     {
 63         if (is_bridge[u])
 64         {
 65             ans--;
 66             is_bridge[u]=0;
 67         }
 68         u=fa[u];
 69         if (is_bridge[v])
 70         {
 71             ans--;
 72             is_bridge[v]=0;
 73         }
 74         v=fa[v];
 75     }
 76 }
 77 void add(int u,int v)
 78 {
 79     edge[cnt].v=v;
 80     edge[cnt].next=head[u];
 81     head[u]=cnt++;
 82     edge[cnt].v=u;
 83     edge[cnt].next=head[v];
 84     head[v]=cnt++;
 85 }
 86 
 87 void init()
 88 {
 89     dfs_clock=0;
 90     ans=cnt=0;
 91     memset(is_bridge,0,sizeof(is_bridge));
 92   //  memset(vis,0,sizeof(vis));
 93     memset(head,-1,sizeof(head));
 94     memset(dfn,-1,sizeof(dfn));
 95     for (int i=1;i<=n;i++) fa[i]=i;
 96    // for (int i=0;i<=n;i++) mp[i].clear();
 97 }
 98 
 99 int main()
100 {
101      int cas=0;
102      //freopen("input.txt","r",stdin);
103      //freopen("out.txt","w",stdout);
104      while (scanf("%d%d",&n,&m)!=EOF)
105      {
106          if (n==0&&m==0break;
107          init();
108          for (int i=0;i<m;i++)
109          {
110              int u,v;
111              scanf("%d%d",&u,&v);
112              //mp[u].push_back(v);
113             // mp[v].push_back(u);
114              add(u,v);
115          }
116 
117          dfs(1,0);
118          int Q;
119          scanf("%d",&Q);
120          printf("Case %d:\n",++cas);
121          while (Q--)
122          {
123              int u,v;
124              scanf("%d%d",&u,&v);
125              LCA(u,v);
126              printf("%d\n",ans);
127          }
128          puts("");
129      }
130 return 0;
131 }

posted on 2015-02-13 00:43  forgot93  阅读(114)  评论(0编辑  收藏  举报

导航