【POJ2117】Electricity [tarjan 割点]
一个无向图 去掉一个点后最多能被分为多少个部分
输入要注意是n m同时为0才停.... n,m可能有一个为零 别问我为什么知道...
其实没太弄懂.....再看看吧
#include<iostream> #include<cstdio> #include<queue> #include<cstring> #include<cmath> #include<stack> #include<algorithm> using namespace std; #define ll long long #define rg register const int N=10000+5,M=200000+5,inf=0x3f3f3f3f,P=19650827; int n,m,cnt=0,ans=-inf; int dfn[N],low[N],cut[N],idx=0; template <class t>void rd(t &x){ x=0;int w=0;char ch=0; while(!isdigit(ch)) w|=ch=='-',ch=getchar(); while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); x=w?-x:x; } int head[N],tot=0; struct edge{int u,v,nxt;}e[N*10]; void add(int u,int v){ e[++tot]=(edge){u,v,head[u]};head[u]=tot; } void tarjan(int u,int fa){ dfn[u]=low[u]=++idx; for(int i=head[u],v;i;i=e[i].nxt){ v=e[i].v; if(!dfn[v]){ tarjan(v,u),low[u]=min(low[u],low[v]); if(dfn[u]<=low[v]) ++cut[u]; } else if(v!=fa&&dfn[v]<low[u]) low[u]=dfn[v]; } } void clean(){ tot=idx=cnt=0;ans=-inf; for(int i=0;i<n;++i) head[i]=dfn[i]=cut[i]=low[i]=0; } int main(){ while(scanf("%d%d",&n,&m)==2&&(n||m)){ clean(); for(int i=1,u,v;i<=m;++i) rd(u),rd(v),add(u,v),add(v,u); for(int i=0;i<n;++i) if(!dfn[i]) { ++cnt; tarjan(i,-1); --cut[i]; } for(int i=0;i<n;++i) ans=max(ans,cut[i]); printf("%d\n",ans+cnt); } return 0; }