蓝书3.6 割点与桥

T1 Network poj 1144

题目大意:

求割点

思路:

裸题

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<algorithm>
 7 #include<queue>
 8 #include<vector>
 9 #define ll long long
10 #define inf 2139062143
11 #define MAXN 10100
12 using namespace std;
13 inline int read()
14 {
15     int x=0,f=1;char ch=getchar();
16     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
17     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
18     return x*f;
19 }
20 int n,res,stp,rts,cnt,fst[MAXN],to[MAXN<<2],nxt[MAXN<<2],dfn[MAXN],low[MAXN],ans[MAXN];
21 void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;}
22 void tarjan(int x)
23 {  
24     dfn[x]=low[x]=++stp;
25     for(int i=fst[x];i;i=nxt[i])
26         if(!dfn[to[i]])
27         {
28             tarjan(to[i]);
29             low[x]=min(low[x],low[to[i]]);
30             if(low[to[i]]>=dfn[x]&&x!=1)
31                 if(!ans[x]) ans[x]=1,res++;
32                 else ans[x]=1;
33             else if(x==1) rts++;
34         }
35         else low[x]=min(low[x],dfn[to[i]]);
36 }
37 int main()  
38 {  
39     while(scanf("%d",&n)&&n)
40     {
41         memset(fst,0,sizeof(fst));
42         memset(ans,0,sizeof(ans));
43         memset(dfn,0,sizeof(dfn));
44         res=rts=stp=0;int a,b;
45         while(scanf("%d",&a)&&a)
46             while(getchar()!='
') {scanf("%d",&b);add(a,b);add(b,a);}
47         tarjan(1);
48         if(rts>1) res++;
49         printf("%d
",res);
50     }
51 }
View Code

T2 Electricity poj 2117

题目大意:

去掉一个点使剩余的联通块数量最大

思路:

求一下每个割点连了几个联通分量 输出最大的

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<algorithm>
 7 #include<queue>
 8 #include<vector>
 9 #define ll long long
10 #define inf 2139062143
11 #define MAXN 10100
12 using namespace std;
13 inline int read()
14 {
15     int x=0,f=1;char ch=getchar();
16     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
17     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
18     return x*f;
19 }
20 int n,m,sum,res,stp,rts,cnt,fst[MAXN],to[MAXN<<3],nxt[MAXN<<3],dfn[MAXN],low[MAXN],ans[MAXN];
21 void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;}
22 void tarjan(int x,int fa)
23 {  
24     dfn[x]=low[x]=++stp;
25     for(int i=fst[x];i;i=nxt[i])
26         if(!dfn[to[i]])
27         {
28             tarjan(to[i],x);
29             low[x]=min(low[x],low[to[i]]);
30             if(low[to[i]]>=dfn[x]) ans[x]++;
31         }
32         else if(dfn[to[i]]<dfn[x]&&to[i]!=fa)low[x]=min(low[x],dfn[to[i]]);
33 }
34 int main()
35 {
36     int a,b;
37     while(scanf("%d%d",&n,&m)==2&&n)
38     {
39         memset(ans,0,sizeof(ans));stp=sum=cnt=0,res=-1;
40         memset(dfn,0,sizeof(dfn));memset(fst,0,sizeof(fst));
41         for(int i=0;i<m;i++){a=read(),b=read();add(a,b);add(b,a);}
42         for(int i=0;i<n;i++)
43             if(!dfn[i]) {sum++;tarjan(i,-1);ans[i]--;}
44         for(int i=0;i<n;i++) res=max(res,ans[i]);
45         printf("%d
",sum+res);
46     }
47 }
View Code

T3 BLO bzoj 1123

题目大意:

一个无向图 求第i个点去掉,将有多少对点不能互通

思路:

去掉之后和其他的点肯定不能联通 所以每个点答案加上(n-1)*2

如果是割点就排列组合一下四周的点双联通分量

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<algorithm>
 7 #include<queue>
 8 #include<vector>
 9 #define ll long long
10 #define inf 2139062143
11 #define MAXN 100100
12 using namespace std;
13 inline int read()
14 {
15     int x=0,f=1;char ch=getchar();
16     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
17     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
18     return x*f;
19 }
20 int n,m,res,stp,rts,cnt,sz[MAXN],fst[MAXN],to[MAXN*10],nxt[MAXN*10],dfn[MAXN],low[MAXN];
21 ll ans[MAXN];
22 void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;}
23 void tarjan(int x)
24 {
25     int t=0;sz[x]=1;
26     dfn[x]=low[x]=++stp;
27     for(int i=fst[x];i;i=nxt[i])
28         if(!dfn[to[i]]) 
29         {
30             tarjan(to[i]);
31             sz[x]+=sz[to[i]],low[x]=min(low[x],low[to[i]]);
32             if(low[to[i]]>=dfn[x])
33                 ans[x]+=(ll)t*sz[to[i]],t+=sz[to[i]];
34         }
35         else low[x]=min(low[x],dfn[to[i]]);
36     ans[x]+=(ll)t*(n-t-1);
37 }
38 int main()
39 {
40     n=read(),m=read();int a,b;
41     while(m--) {a=read(),b=read();add(a,b);add(b,a);}
42     tarjan(1);
43     for(int i=1;i<=n;i++)
44         printf("%lld
",(ans[i]+n-1)<<1);
45 }
View Code
原文地址:https://www.cnblogs.com/yyc-jack-0920/p/9375818.html