zoukankan      html  css  js  c++  java
  • sdut 2506 完美网络 夜

    http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2506

    连通分量   缩点后形成新的图(不用新建也可以) 是一个森林

    如果缩点后是就剩一个点 则答案为 0

    否则 对于缩点后的某一个点   如果和它相连点(缩点后的)有大于等于2个 则无需再连

    如果和它相连的有一个点 则需要加一个边连接它 如果没有点和它相连 则需要加两条

    统计总共需要加的边的个数sum 因为每条边连接两个点 所以答案为 (sum+1)/2

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<map>
    #include<vector>
    #include<stack>
    #include<queue>
    #include<set>
    #include<algorithm>
    #define LL long long
    using namespace std;
    const int N=5015;
    const int M=10005;
    int head[N],I;
    struct node
    {
        int j,next;
    }side[M*2];
    int dfn[N],low[N],f[N],deep;
    bool visited[N],in[N];
    stack<int>st;
    set<int>numt[N];
    void add(int i,int j)
    {
        side[I].j=j;
        side[I].next=head[i];
        head[i]=I++;
    }
    void dfs(int x,int pre)
    {
        dfn[x]=low[x]=deep++;
        st.push(x);
        in[x]=true;
        visited[x]=true;
        for(int t=head[x];t!=-1;t=side[t].next)
        {
            int j=side[t].j;
            if(j==pre)
            continue;
            if(!visited[j])
            {
                dfs(j,x);
                low[x]=min(low[x],low[j]);
            }else if(in[j])
            {
                low[x]=min(low[x],dfn[j]);
            }
        }
        if(low[x]==dfn[x])
        {
            while(st.top()!=x)
            {
                in[st.top()]=false;
                f[st.top()]=x;
                st.pop();
            }
            in[st.top()]=false;
            f[st.top()]=x;
            st.pop();
        }
    }
    int main()
    {
        //freopen("data.in","r",stdin);
        int T;
        scanf("%d",&T);
        while(T--)
        {
           memset(head,-1,sizeof(head));
           I=0;
           int n,m;
           scanf("%d %d",&n,&m);
           while(m--)
           {
               int l,r;
               scanf("%d %d",&l,&r);
               add(l,r);
               add(r,l);
           }
           while(!st.empty())
           st.pop();
           memset(in,false,sizeof(in));
           memset(visited ,false,sizeof(visited));
           deep=1;
           int treenum=0;
           for(int i=1;i<=n;++i)
           {
               if(!visited[i])
               {
                   dfs(i,-1);
                   ++treenum;
               }
           }
           for(int i=1;i<=n;++i)
           numt[i].clear();
           for(int i=1;i<=n;++i)
           {
               for(int t=head[i];t!=-1;t=side[t].next)
               {
                   int j=side[t].j;
                   if(f[i]!=f[j])
                   {
                       numt[f[i]].insert(f[j]);
                   }
               }
           }
           int leftnum=0;
           int sum=0;
           for(int i=1;i<=n;++i)
           {
               if(f[i]==i)
               {
                   if(numt[i].size()==0)
                   {sum+=2;leftnum++;}
                   if(numt[i].size()==1)
                   {sum+=1;leftnum++;}
               }
           }
           if(treenum==1&&leftnum==1)
           {
               printf("0\n");
           }else
           {
               printf("%d\n",(sum+1)/2);
           }
        }
        return 0;
    }
    

      

  • 相关阅读:
    第12章学习笔记
    尝试用华为Matepad平板在华为云openEuler做SM系列测试实验
    flex tree xml相关
    asp.net乱码问题
    ArcGIS Server for Flex 资源收集
    asp.net 读写excel
    Geoprocessor 使用
    上传控件
    html页面布局 水平居中 垂直居中
    ArcGIS Engine 代码收集贴
  • 原文地址:https://www.cnblogs.com/liulangye/p/2811102.html
Copyright © 2011-2022 走看看