NOIPの模拟_2016_8_11_t2_种树

来源:互联网 发布:网络被攻击了怎么办 编辑:程序博客网 时间:2024/06/02 00:44

这里写图片描述
这里写图片描述

题目の大意:

现在有一个无向图,我们可以删去一个节点和与其相连的边,使得修改后的图变成一棵树,求所有可能的方案和方案数~

比赛时の想法:

暴力枚举每一个删除的点,然后暴力判断一下删去这个点和他相连的边后图是否变成一颗树,m=n-1时删去一个度数为1的边。

正解:

一开始有n个点,在删去一个点后成为一颗树,那么树中就有n-2条边,当前删去的点如果是合法的,那么它的度数就是m-(n-2)但是考虑到删去一个点后可能把图成两个部分,所以当这个点时无向图的割点时这个点也是不合法的,那么我们直接tarjan求割点就好了

贴代码~

var    dfn,low,fa:array[0..100005]of longint;    a:array[0..100005,0..105]of longint;    bz,b:array[0..100005]of boolean;    i,j,k,l,n,m,x,y,p,ans:longint;function min(x,y:longint):longint;begin    if x>y then exit(y) else exit(x);end;procedure dfs(x:longint);var    i,j,son:longint;begin    b[x]:=true;    inc(p);    dfn[x]:=p;    low[x]:=p;    son:=0;    for i:=1 to a[x,0] do    begin        if b[a[x,i]]=false then        begin            inc(son);            fa[a[x,i]]:=x;            dfs(a[x,i]);            low[x]:=min(low[a[x,i]],low[x]);            if (dfn[x]=1) and (son>=2) then bz[x]:=true else            if (dfn[x]>1) and (low[a[x,i]]>=dfn[x]) then bz[x]:=true;        end else        if fa[x]<>a[x,i] then low[x]:=min(low[x],dfn[a[x,i]]);    end;end;begin   // assign(input,'2.in'); reset(input);    readln(n,m);    for i:=1 to m do    begin        readln(x,y);        inc(a[x,0]);        a[x,a[x,0]]:=y;        inc(a[y,0]);        a[y,a[y,0]]:=x;    end;    dfs(1);    x:=m-n+2;    ans:=0;    for i:=1 to n do        if (a[i,0]=x) and (bz[i]=false) then inc(ans);    writeln(ans);    for i:=1 to n do        if (a[i,0]=x) and (bz[i]=false) then write(i,' ');    writeln;  //  close(input);end.
0 0
原创粉丝点击