您的位置:首页 > 其它

HDU 4612 Warm up 解题报告

2013-07-25 19:27 375 查看
比赛

题目

题意:给出n个点和m条边的图,存在重边,问加一条边以后,剩下的桥的数量最少为多少。

解法:先用tarjan缩点变成一棵树,然后求树的直径,显然,用一条边将直径的两个端点连起来可以让剩余的桥数量最少。要注意会有重边,在tarjan里面要判一下。

//time 1031MS
//memory 31340K
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#define MAXN 300015
#define MAXM 4000015
using namespace std;
struct Edge{
int v,next;
}edge[MAXM],edge2[MAXM];
int head[MAXN],en;
int head2[MAXN],en2;
int id[MAXN],dfn[MAXN],low[MAXN],sta[MAXN],top,num,scc;
int n,m;
bool vis[MAXN];
void init()
{
memset(head,-1,sizeof(head));
memset(vis,0,sizeof(vis));
en = 0;
top = 0;
scc=num = 0;memset(dfn,0,sizeof(dfn));
}
void addedge(int u,int v)
{
edge[en].v = v;
edge[en].next = head[u];
head[u] = en++;
}
void addedge2(int u,int v)
{
edge2[en2].v = v;
edge2[en2].next = head2[u];
head2[u] = en2++;
}
void tarjan(int u,int fa)
{
dfn[u] = low[u] = ++num;
sta[++top] = u;
int cnt=0;
for(int i = head[u]; i != -1; i = edge[i].next)
{
int v = edge[i].v;
if(!dfn[v])
{
tarjan(v,u);
low[u] = min(low[u],low[v]);
}
else if (fa==v)
{
if (cnt) low[u] = min(low[u],dfn[v]);//重边
cnt++;
}
else low[u] = min(low[u],dfn[v]);
}
if(dfn[u]==low[u])
{
int x;
scc++;
do
{
x = sta[top--];
id[x] = scc;
}while(x!=u);
}
}
void build()
{
en2 = 0;
memset(head2,-1,sizeof(head2));
for(int i = 1; i <= n; i++)
{
for(int j = head[i]; j!=-1; j = edge[j].next)
{
int v = edge[j].v;
if(id[i]!=id[v])
addedge2(id[i],id[v]);
}
}
}
int ans;
int dfs(int u,int p)
{
int max1=0,max2=0;
for (int i=head2[u];i!=-1;i=edge2[i].next)
{
int v=edge2[i].v;
if (v==p) continue;
int tmp=dfs(v,u)+1;
if (max1<tmp) max2=max1,max1=tmp;
else if (max2<tmp) max2=tmp;
}
ans=max(ans,max1+max2);
return max1;
}
int main()
{
//freopen("/home/qitaishui/code/in.txt","r",stdin);
int u,v;
while(scanf("%d%d",&n,&m)&&(n+m))
{
init();
//cout<<n<<m<<endl;
for(int i = 0; i < m; i++)
{
scanf("%d%d",&u,&v);
if (v==u) continue;
addedge(u,v);
addedge(v,u);
//cout<<u<<" "<<v<<endl;
}

tarjan(1,-1);
build();
ans=0;
dfs(1,-1);
printf("%d\n",scc-ans-1);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: