HDU 4612 Warm up
13:
key word:
桥 ,数的路径
题意:求一个无向图的桥,然后加一条边使桥的数目最小。
先求出原图的桥数,然后找树的最长路径,答案就是桥数-最长路径;
ADD question:假如减去一条路径求最多有多少条桥;
CODE:
#pragma comment(linker,"/STACK:102400000,102400000")
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<math.h>
#include<stack>
using namespace std;
const int N=200010;
const int M=1000020;
struct node
{
int v,next;
}e[M*2];
int head[N];
int dfn[N],low[N],dp[N][2];
int vis[M];
int n,m,cnt,ans;
void add(int u,int v)
{
e[cnt].v=v;
e[cnt].next=head[u];
head[u]=cnt++;
}
void dfs(int u)
{
dfn[u]=low[u]=cnt++;
dp[u][0]=dp[u][1]=0;
for (int i=head[u];i!=-1;i=e[i].next)
{
int j=e[i].v;
if (!vis[i>>1])
{
vis[i>>1]=1;
if (dfn[j]==0)
{
dfs(j);
ans+=dfn[u]<low[j];
int tmp=dp[j][0]+(dfn[u]<low[j]);
if (tmp>dp[u][0]){
dp[u][1]=dp[u][0],dp[u][0]=tmp;}
else
if (tmp>dp[u][1]) dp[u][1]=tmp;
low[u]=min(low[u],low[j]);
}
else low[u]=min(low[u],dfn[j]);
}
}
}
int main()
{
while (scanf("%d%d",&n,&m))
{
if (n==0&&m==0) break;
cnt=ans=0;
memset(head,-1,sizeof(head));
memset(low,0,sizeof(low));
memset(dfn,0,sizeof(dfn));
while (m--)
{
int u,v;
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
cnt=1;
memset(vis,0,sizeof(vis));
dfs(1);
int tmp=0;
for (int i=1;i<=n;i++)
tmp=max(tmp,dp[i][0]+dp[i][1]);
printf("%d\n",ans-tmp);
}
return 0;
}