題意
給你一個無向圖
問你最少添加多少條邊可以使得他變成邊雙圖
題解
直接雙連通縮點
得到一顆樹
然后答案是葉子節點/2向上取整
取法是每一次找兩個LCA深度最小的葉子,兩個連邊就可以了
然后不知道為什么,我的統計入度為1的節點的寫法,一直WA
對拍也不出事。。真的是一定是OJ的問題
最后改成FYC的暴力dfs寫法才AC
using namespace std;
const
int N=
20010;
int n,
m;
struct
qq{int x,y,last;}e[N
*2];
int num,
last[N];
void init (
int x,
int y)
{num++;e[num].
x=
x;e[num].
y=
y;e[num].
last=
last[
x];
last[
x]=num;
}
int low[N],dfn[N],id;
int sta[N],top=
0;
int belong[N],cnt;
void dfs (
int x,
int fa)
{low[
x]=dfn[
x]=++id;sta[++top]=
x;
for (
int u=
last[
x];u!=-
1;u=e[u].
last){
int y=e[u].
y;
if (
y==fa)
continue;
if (dfn[
y]==-
1){dfs(
y,
x);low[
x]=min(low[
x],low[
y]);}
else low[
x]=min(low[
x],dfn[
y]);}
if (low[
x]==dfn[
x]){cnt++;
int i;
do{i=sta[top--];belong[i]=cnt;}
while (i!=
x);}
}
int du[N];
int ans=
0;
void dfs1 (
int x,
int fa)
{
int tot=
0;
for (
int u=
last[
x];u!=-
1;u=e[u].
last){
int y=e[u].
y;
if (
y==fa)
continue;dfs1(
y,
x);tot++;}
if (tot==
0) ans++;
if (
x==belong[
1]&&tot==
1) ans++;
}
int main()
{memset(dfn,-
1,sizeof(dfn));num=
0;memset(
last,-
1,sizeof(
last));scanf(
"%d%d",&n,&
m);
for (
int u=
1;u<=
m;u++){
int x,
y;scanf(
"%d%d",&
x,&
y);init(
x,
y);init(
y,
x);}dfs(
1,
0);num=
0;memset(
last,-
1,sizeof(
last));
for(
int i=
1;i<=
m*2;i+=
2){
int x=e[i].
x,
y=e[i].
y;
if(belong[
x]!=belong[
y]) init(belong[
x],belong[
y]),init(belong[
y],belong[
x]);}
if (num==
0) {
printf(
"0\n");
return 0;}dfs1(belong[
1],
0);
printf(
"%d\n",(ans+
1)/
2);
return 0;
}
總結
以上是生活随笔為你收集整理的bzoj 1718: [Usaco2006 Jan] Redundant Paths 分离的路径的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。