Uvalive5135_mining your own business

Source: Internet
Author: User

Good question. For an undirected graph, find the minimum number of vertices that are black, and delete any vertex. Each vertex is connected to at least one black dot.

I did not know how to do it at the beginning. Read the White Book. For a Unicom component, if it has two or more cut points, then any point in the middle of the component does not need to be colored. If this Unicom component happens to have a cut point, the component needs to be colored on any of the non-cut points. If the component does not have a cut point, take any two dyes.

It is not difficult to understand, because at most one vertex can be deleted. Therefore, if the deleted vertex is not a cut point, the component is absolutely connected. At the same time, you can use the cut point to connect the component outside, if you delete a cut point, it is not connected to the inside, so at least one black spot is required. If there are two cut points, obviously, no matter which point you remove, this component is connected to the outside.

With this idea, the question is simple.

 

 

Summon code:

 

 

Solution 1: Find all connected components, determine the number of cut points for each connected component, and update the answer.

#include <iostream>#include <cstdio>#include <cstring>#include <vector>#define maxn 201000typedef long long ll;using namespace std;int first[maxn],next[maxn],to[maxn],edge;//graphvector<int> bcc[maxn];int N,bccnum;//the bcc dataint iscut[maxn],belong[maxn],d[maxn],low[maxn],child;int U[maxn],V[maxn],stack[maxn],top;//stackint n,m,cas=0,T;ll ans,tot;void _init(){    ans=1,tot=0,edge=-1,child=bccnum=0,top=0;    for (int i=1; i<=n; i++) first[i]=-1,d[i]=low[i]=iscut[i]=belong[i]=0;}void addedge(int uu,int vv){    edge++;    to[edge]=vv,next[edge]=first[uu],first[uu]=edge;    edge++;    to[edge]=uu,next[edge]=first[vv],first[vv]=edge;}void dfs(int cur,int fa){    d[cur]=low[cur]=d[fa]+1;    for (int i=first[cur]; i!=-1; i=next[i])    {        if (to[i]==fa) continue;        if (!d[to[i]])        {            if (fa==0) child++;            top++; U[top]=cur,V[top]=to[i];            dfs(to[i],cur);            low[cur]=min(low[cur],low[to[i]]);            if (low[to[i]]>=d[cur])            {                iscut[cur]=1;                bccnum++,bcc[bccnum].clear();                for (;;top--)                {                    if (belong[U[top]]!=bccnum) belong[U[top]]=bccnum,bcc[bccnum].push_back(U[top]);                    if (belong[V[top]]!=bccnum) belong[V[top]]=bccnum,bcc[bccnum].push_back(V[top]);                    if (U[top]==cur && V[top]==to[i])                    {                        top--;                        break;                    }                }            }        }        else low[cur]=min(low[cur],d[to[i]]);    }    if (fa==0 && child==1) iscut[cur]=0;}int main(){    while (scanf("%d",&m) && (m))    {        n=-1;        for (int i=1; i<=m; i++)        {            scanf("%d%d",&U[i],&V[i]);            n=max(n,max(U[i],V[i]));        }        _init();        for (int i=1; i<=m; i++) addedge(U[i],V[i]);        for (int i=1; i<=n; i++)            if (!d[i])            {                if (first[i]==-1)                {                    tot++;                    continue;                }                child=0;                dfs(i,0);            }        for (int i=1; i<=bccnum; i++)        {            int cutnum=0;            for (unsigned j=0; j<bcc[i].size(); j++)                if (iscut[bcc[i][j]]) cutnum++;            if (cutnum==1)            {                tot++;                ans*=bcc[i].size()-1;            }            else if (cutnum==0)            {                tot+=2;                ll tmp=bcc[i].size();                ans*=tmp*(tmp-1)/2;            }        }        printf("Case %d: %lld %lld\n",++cas,tot,ans);    }    return 0;

 

Solution 2: mark all the cut points, starting from the non-cut point each time, to see how many non-cut points can be reached, and the total number of cut points adjacent, (In fact, it traverses the UNICOM component, but the implementation is simpler ).

#include <iostream>#include <cstdio>#include <cstring>#define maxn 200200typedef long long ll;using namespace std;int first[maxn],to[maxn],next[maxn],edge;int U[maxn],V[maxn];int d[maxn],low[maxn],tag[maxn];bool iscut[maxn],vis[maxn];int n,m,tot,child,sum,cut;ll ans;void _init(){    tot=0,ans=1,edge=-1;    for (int i=1; i<=n; i++)        first[i]=-1,iscut[i]=vis[i]=false,tag[i]=low[i]=d[i]=0;}void addedge(int uu,int vv){    edge++;    to[edge]=vv,next[edge]=first[uu],first[uu]=edge;    edge++;    to[edge]=uu,next[edge]=first[vv],first[vv]=edge;}void dfs(int cur,int fa){    d[cur]=low[cur]=d[fa]+1;    for (int i=first[cur]; i!=-1; i=next[i])    {        if (to[i]==fa) continue;        if (!d[to[i]])        {            if (fa==0) child++;            dfs(to[i],cur);            low[cur]=min(low[cur],low[to[i]]);            if (low[to[i]]>=d[cur]) iscut[cur]=true;        }        else low[cur]=min(low[cur],d[to[i]]);    }    if (fa==0 && child==1) iscut[cur]=false;}void visit(int cur,int TAG){    sum++,vis[cur]=true;    for (int i=first[cur]; i!=-1; i=next[i])    {        if (iscut[to[i]] && tag[to[i]]!=TAG) cut++,tag[to[i]]=TAG;            else if (!iscut[to[i]] && !vis[to[i]]) visit(to[i],TAG);    }}int main(){    int cas=0;    while (scanf("%d",&m) && (m))    {        n=0;        for (int i=1; i<=m; i++) scanf("%d%d",&U[i],&V[i]),n=max(n,max(U[i],V[i]));        _init();        for (int i=1; i<=m; i++) addedge(U[i],V[i]);        for (int i=1; i<=n; i++)            if (!d[i])            {                child=0;                dfs(i,0);            }        for (int i=1; i<=n; i++)            if (!vis[i] && !iscut[i])            {                cut=sum=0;                visit(i,i);                if (cut==0) tot+=2,ans*=(ll)sum*(sum-1)/2;                    else if (cut==1) tot++,ans*=sum;            }        printf("Case %d: %d %lld\n",++cas,tot,ans);    }    return 0;}
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.