• C++ CF862B Mahmoud and Ehab and the bipartiteness


    题意翻译

    给出n个点,n-1条边,求再最多再添加多少边使得二分图的性质成立

    By @partychicken

    (为了尽量更清晰的说明题意,以下为个人附加的内容)

    就像这样(黑边为原本就有的边,红色边的数量为需要求出的解):

    图片来自:https://www.luogu.org/blog/ACdreamer/solution-cf862b

    输入输出样例

    输入样例1:

    3
    1 2
    1 3

    输出样例1:

    0

    输入样例2:

    5
    1 2
    2 3
    3 4
    4 5

    输出样例2:

    2

    题目链接: https://www.luogu.org/problemnew/show/CF862B


    个人思路:

    • 看起来是个二分图染色的裸题,就可以向二分图染色的方向进行一些考虑.
    • 由于数据不保证给定的图是联通图,所以要准备到图不是联通图的可能。因此,我们要增加一个vis数组(用于判断某个点是否被访问过),并对每个点进行BFS.
    • 由题意可知:对于我们要求的结果来说,结果所代表的理想的图的每一个点,都连接着另一颜色的点集的所有点。根据乘法原理和我们推理所得到的结论,可以得出这样一个事实:对于结果我们想要推理出的图来说,她的边的数量为一种颜色的点的数量*另一种颜色的点的数量.
    • 因为我们要求得的结果为:最多需要再添加的边的数量 因此,我们只需要将求得的边的总数量再减去图中一开始就有的边的数量即可。
    • 由此,可得最终结果为:最少(之所以说"最少"是因为给定图可能不是联通图)的一种点的数量*另一种点的数量-n+1.

    #include<cstdio>
    #include<iostream>
    #include<queue>
    #include<cstring>
    using namespace std;
    const int N=200005,M=200005;
    long long n,m,cnt=0,head[N],cl[N],vis[N],ansA=0;
    struct Edge{
        int v,w,nxt;
    }e[M];
    void addEdge(int u,int v,int w){
        e[++cnt].v=v;
        e[cnt].w=w;
        e[cnt].nxt=head[u];
        head[u]=cnt;
    }
    long long ans[2]{0,0};
    int bfs(int x){
        queue<int> q;
        q.push(x);
        while(!q.empty()){
            int nowValue=q.front();q.pop();
            for(int i=head[nowValue];i;i=e[i].nxt){
                int nowV=e[i].v;
                if(cl[nowV]==-1){
                    //cout<<"nowV:"<<nowV<<endl;
                    //cout<<"cl[nowValue]="<<cl[nowValue]<<endl;
                    cl[nowV]=cl[nowValue]^1;
                    //cout<<"cl["<<nowV<<"]="<<cl[nowV]<<endl;
                    ans[cl[nowV]]++;
                    q.push(nowV);
                }
                if(cl[nowV]==cl[nowValue]){
                    return -1;
                }
                
            }
        }
        //cout<<"ans[0]:"<<ans[0]<<",ans[1]:"<<ans[1]<<endl;
        return min(ans[0],ans[1]);
    }
    int main(){
        memset(cl,-1,sizeof(cl));
        scanf("%d",&n);
        m=n-1;
        for(int i=1;i<=m;i++){
            int ta,tb;
            scanf("%d%d",&ta,&tb);
            addEdge(ta,tb,1);
            addEdge(tb,ta,1);
        }
        for(int i=1;i<=n;i++){
            if(cl[i]==-1){
                cl[i]=1;
                ans[1]++;
                //cout<<"bfs:"<<i<<endl;
                int tempAns=bfs(i);
                ansA+=ans[0]*ans[1]-n+1;
                memset(ans,0,sizeof(ans));
            }
        }
        printf("%lld
    ",ansA);
        return 0;
    }
  • 相关阅读:
    HihoCoder 1245:王胖浩与三角形 三角形边长与面积
    C++ 读写注册表
    Codestorm:Counting Triangles 查各种三角形的个数
    2015年10月之 叽里咕噜
    HDU 5523:Game
    Codestorm:Game with a Boomerang
    关于GPU-driver for linux的资料
    ACER NV47H75C 安装CUDA 驱动以及调整屏幕
    服务器GTX590安装CUDA
    观后感,读了几篇博文
  • 原文地址:https://www.cnblogs.com/zbsy-wwx/p/11680705.html
Copyright © 2020-2023  润新知