Poj 3352 and poj 3177 are actually the same, except that 3177 may have a duplicate edge, which requires special judgment.
3352 ask if one side is removed after the transformation and the other side is still connected. 3177 if any two points after the transformation have at least two different paths, they are actually the same. They are all first located at the bridge, scale each component into a tree. The result is (the number of leaves + 1)/2.
#define N 1005vector<int> v[N];int low[N];bool vis[N];int du[N];int cnt;void dfs(int u,int fa){ vis[u] = 1; int i; low[u] = ++cnt; for(i=0;i<v[u].size();i++){ int vv = v[u][i]; if(vv == fa)continue; if(!vis[vv]){ dfs(vv,u); } if(low[vv]<low[u])low[u] = low[vv]; }}int main(){ int n,m; while(scanf("%d%d",&n,&m) != -1){ int i,j; for(i=0;i<=n;i++){ v[i].clear(); vis[i] = 0; du[i] = 0 ; } while(m--){ int a,b; scanf("%d%d",&a,&b); v[a].push_back(b); v[b].push_back(a); } cnt=0; dfs(1,1); for(i=1;i<=n;i++){ for(j=0;j<v[i].size();j++){ int u = v[i][j]; if(low[i]!=low[u])du[low[i]]++; } } int ans=0; for(i=1;i<=n;i++){ if(du[i] == 1)ans++; } printf("%d\n",(ans+1)/2); } return 0;}
Poj 3177
I don't understand
2 2
1 2
1 2
The answer to this set of data is 1. You can see that 1 and 2 are already in the same dual-connected component and there is no need to add additional edges. The data in poj is really weird.
#define N 5005vector<int> v[N];int low[N];bool vis[N];int du[N];int cnt;bool g[N][N];void dfs(int u,int fa){ vis[u] = 1; int i; low[u] = ++cnt; for(i=0;i<v[u].size();i++){ int vv = v[u][i]; if(vv == fa)continue; if(!vis[vv]){ dfs(vv,u); } if(low[vv]<low[u])low[u] = low[vv]; }}int main(){ int n,m; while(scanf("%d%d",&n,&m) != -1){ int i,j; memset(g,0,sizeof(g)); for(i=0;i<=n;i++){ v[i].clear(); vis[i] = 0; du[i] = 0 ; } while(m--){ int a,b; scanf("%d%d",&a,&b); if(!g[a][b]){ v[a].push_back(b); v[b].push_back(a); g[a][b] = g[b][a] = 1; } } cnt=0; dfs(1,1); for(i=1;i<=n;i++){ for(j=0;j<v[i].size();j++){ int u = v[i][j]; if(low[i]!=low[u])du[low[i]]++; } } int ans=0; for(i=1;i<=n;i++){ if(du[i] == 1)ans++; } printf("%d\n",(ans+1)/2); } return 0;}