一场无硝烟的战争即将爆发,蒜头君和花椰妹接到上级任务一破坏敌万通信网终。破坏敌方通信网终并不是一件简单任务,蒜头君和花椰妹只能冬自破坏敌方通信网络中一人节点,认成入节点后,如果现万至少有两人节点无法通信除7已被认的两入节点,就以大禁斗君和艺规还,为了筒化问题,请你计鲁亲,君和花椰妹有多少种方法可以成功破坏敌方通信网络。 输入格式 第一行输入两个整数 n(3 < n 1000)和 m(0 < m 10000),表示敌方有 条电连接 节点(节点编号从 1到n)接来下 m 行,每行有两个整数 a,(1 < a,b n),表示节点 a 和节点通过一条双向电缆连接。输出格式 输出一个整数,表示蒜头君和花椰妹有多少种方法可以成功破坏敌方通信网络.
#include <iostream>
#include <stack>
#include <set>
#include <cstring>
using namespace std;
const int maxm = 1010; // 最大边数
const int maxn = 110; // 最大点数
struct edge {
int u, v;
int next;
} E[maxm];
int p[maxn], eid = 0;
void init() {
memset(p, -1, sizeof(p));
eid = 0;
}
void insert(int u, int v) {
E[eid].u = u;
E[eid].v = v;
E[eid].next = p[u];
p[u] = eid++;
}
int times =0;
int dfn[maxn],low[maxn];
int ans=0;//连通分量个数
bool iscut[maxn];
bool vis[maxn];
int cnt=1;
void dfs(int u,int fa,int x){
if(u==x) return;
dfn[u]=low[u]=++times;
int child =0;//根节点子节点数
for(int i=p[u];i!=-1;i=E[i].next){
int v=E[i].v;
if(dfn[v]==0){
++child;
vis[v]=1;
ans++;
dfs(v,u,x);
low[u]=min(low[u],low[v]);
if(low[v]>=dfn[u]){
iscut[u]=true;
}
}
else if(dfn[v]<dfn[u]&&v!=fa){
low[u]=min(low[u],dfn[v]);
}
}
if(fa<0&&child==1){
iscut[u]=false;
}
}
int main() {
init();
int n, m;
cin >> n >> m;
for (int i = 0; i < m; ++i) {
int u, v;
cin >> u >> v;
insert(u, v);
insert(v, u);
}
for(int i=1;i<=n;i++){
if(vis[i]==0) {
memset(dfn,0,sizeof(dfn));
memset(iscut,0,sizeof(iscut));
times=ans=0;
if(i==1) dfs(2,-1,i);
else dfs(1,-1,i);
if(ans>2) cnt+=n-1;
else if(ans==2){
if(n!=3) cnt+=n-2;
}
else if(ans==1){
int sum=0;
for(int j=1;j<=n;j++){
if(iscut[j]) sum++;
}
cnt+=sum;
}
}
}
cout<<cnt/2;
return 0;
}