POJ 3352 跟POJ 3177其实是一样的,只不过3177可能有重边,要特判。
3352问改造后去掉一条边仍然连通,3177问改造后任意两点至少有两条不同的路,其实是一样的,都是先找出桥,把各分量缩成一点变成一棵树,结果就是(子叶数+1)/2
#define N 1005
vector<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
这里我不明白
2 2
1 2
1 2
为啥这组数据的答案是1,你看看,1,2已经处在同一个双连通分量里已经没有必要再添加额外的边了,poj的数据真怪异
#define N 5005
vector<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;
}