您的位置:首页 > 其它

POJ 3694 Network

2015-02-13 00:43 288 查看
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
,low
,is_bridge
,dfs_clock;
14 int fa
;
15 int vis
;
16 int head
;
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()
{
int cas=0;
//freopen("input.txt","r",stdin);
//freopen("out.txt","w",stdout);
while (scanf("%d%d",&n,&m)!=EOF)
{
if (n==0&&m==0) break;
init();
for (int i=0;i<m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
//mp[u].push_back(v);
// mp[v].push_back(u);
add(u,v);
}

dfs(1,0);
int Q;
scanf("%d",&Q);
printf("Case %d:\n",++cas);
while (Q--)
{
int u,v;
scanf("%d%d",&u,&v);
LCA(u,v);
printf("%d\n",ans);
}
puts("");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: