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