And did a problem of cutting points.
It can be found that if boom is not in the cutting point then there is no effect, so we only discuss the situation of cutting points.
After finding all the cut points, the whole graph is divided into several unicom blocks. We discuss the number of cut points contained in the Unicom block.
If there is no cut point, then we only need to set up two exits, to prevent the establishment of an exit and this exit blew up.
If there is a cut point, we must establish an exit (not at the cutting point).
If there are two cut points, we do not need to establish an exit, because one explodes when we can go out from the other.
So first Tarjan to cut point and then DFS a bit of each unicom block is good.
At first the VIS array got the bool type but I used the timestamp 2333333333333.
#include <iostream> #include <cstdio> #include <cstring> #define LL long long using namespace std;
int n,m,cnt,num,tot,deg,ans1,t,cases,root;
ll Ans2;
int head[505],dfn[505],low[505],vis[505];
BOOL cut[505];
int next[1005],list[1005];
inline int read () {int a=0,f=1; char C=getchar (); while (c< ' 0 ' | |
C> ' 9 ') {if (c== '-') f=-1; C=getchar ();}
while (c>= ' 0 ' &&c<= ' 9 ') {a=a*10+c-' 0 '; C=getchar ();}
return a*f;
} inline void Insert (int x,int y) {next[++cnt]=head[x];
head[x]=cnt;
List[cnt]=y;
} void Tarjan (int x,int f) {Dfn[x]=low[x]=++tot;
for (int i=head[x];i;i=next[i]) if (!dfn[list[i]]) {Tarjan (list[i],x);
Low[x]=min (Low[x],low[list[i]);
if (Low[list[i]]>=dfn[x]) {if (x==root) deg++; else cut[x]=1;
}} else if (list[i]!=f) low[x]=min (Low[x],dfn[list[i]);
} void Dfs (int x) {vis[x]=t; if (Cut[x]) retUrn
cnt++;
for (int i=head[x];i;i=next[i]) {if (cut[list[i]]&&vis[list[i]]!=t) num++,vis[list[i]]=t;
if (!vis[list[i]]) DFS (list[i]);
}} int main () {m=read ();
while (m) {memset (head,0,sizeof (head));
memset (dfn,0,sizeof (DFN));
memset (low,0,sizeof (Low));
memset (cut,0,sizeof (cut));
memset (vis,0,sizeof (VIS)); cnt=tot=n=ans1=t=0;
Ans2=1;
for (int i=1;i<=m;i++) {int u=read (), V=read ();
N=max (N,max (u,v)); Insert (U,V);
Insert (V,U);
} for (int i=1;i<=n;i++) {if (!dfn[i]) Tarjan (root=i,0);
if (deg>=2) cut[root]=1;
deg=0; } for (int i=1;i<=n;i++) if (!vis[i]&&!cut[i]) {t++; cnt=num=0
;
DFS (i);
if (!num) ans1+=2,ans2*=cnt* (cnt-1)/2; if (num==1) ans1++,ans2*=cnt;
} printf ("Case%d:%d%lld\n", ++cases,ans1,ans2);
M=read ();
} return 0; }