Description
Input
Output
Sample Input
7 7 1 2 2 3 3 4 2 5 4 5 5 6 5 7
Sample Output
2
Hint
1 2 3 +---+---+ | | | | 6 +---+---+ 4 / 5 / / 7 +Building new paths from 1 to 6 and from 4 to 7 satisfies the conditions.
1 2 3 +---+---+ : | | : | | 6 +---+---+ 4 / 5 : / : / : 7 + - - - -Check some of the routes:
注意重边。
#include<cstdio> #include<cstring> #include<iostream> #define FOR(i,a,b) for(int i=a;i<=b;++i) #define clr(f,z) memset(f,z,sizeof f) using namespace std; const int mp=5005; const int me=1e5+9; bool vis[mp][mp]; class Edge { public:int v,next; }; class Graph { public: int dfn[mp],e_to[mp],stak[mp]; int dfs_clock,bcc_no,top,edge; int n,m,head[mp]; Edge e[me*2]; void clear() { edge=0;clr(head,-1); } void add(int u,int v) { e[edge].v=v;e[edge].next=head[u];head[u]=edge++; } int tarjan(int u,int fa) { int v,lowu,lowv; dfn[u]=lowu=++dfs_clock; stak[top++]=u; for(int i=head[u];~i;i=e[i].next) { v=e[i].v; if(v==fa)continue;///访问过的树边 if(!dfn[v]) { lowv=tarjan(v,u); lowu=min(lowv,lowu); // if(lowv>dfn[u]) // { // brige++; // } } else if(e_to[v]==-1&&dfn[v]<lowu) lowu=dfn[v]; } if(lowu==dfn[u]) { ++bcc_no; do{ v=stak[--top]; e_to[v]=bcc_no; }while(v!=u); } return lowu; } int id[mp]; void find_bcc() { dfs_clock=top=bcc_no=0; clr(e_to,-1);clr(dfn,0); FOR(i,1,n) if(!dfn[i]) tarjan(i,-1); int u,v; clr(id,0); for(int i=0;i<edge;i+=2) { u=e[i].v;v=e[i^1].v; u=e_to[u];v=e_to[v]; if(u==v)continue; ++id[u];++id[v]; } int ans=0; for(int i=1;i<=bcc_no;++i) if(id[i]==1) ++ans; if(ans!=1)ans=(ans+1)/2; printf("%d\n",ans); } }tc; int main() { int n,m,a,b; while(~scanf("%d%d",&n,&m)) { FOR(i,0,n)FOR(j,0,n)vis[i][j]=0; tc.clear();tc.n=n;tc.m=m; FOR(i,1,m) { scanf("%d%d",&a,&b); if(vis[a][b])continue; vis[a][b]=vis[b][a]=1; tc.add(a,b);tc.add(b,a); } tc.find_bcc(); } }