1 条题解

  • 0
    @ 2025-11-3 0:09:35

    C++ :

    #include<bits/stdc++.h>
    #define Code using
    #define by namespace
    #define wjb std
    Code by wjb;
    int in()
    {
    	int k=0,f=1;
    	char c=getchar();
    	while(c<'0'||c>'9')
    	{
    		if(c=='-')f=-1;
    		c=getchar();
    	}
    	while(c>='0'&&c<='9')k=k*10+c-'0',c=getchar();
    	return k*f;
    }
    void out(int x)
    {
    	if(x<0)putchar('-'),x=-x;
    	if(x<10)putchar(x+'0');
    	else out(x/10),putchar(x%10+'0');
    }
    const int N=1e5+10;
    vector<int>e[N]; // 存储边 
    bool b[N]; // 这个点是否被访问过了 
    void dfs(int u,int &s1,int &s2,bool f) // 注意这里的 s1 和 s2 要引用传参 
    // 当前点在 u,染了 s1 个红色,s2 个蓝色,f=1 表示当前要染红色,f=0 表示当前要染黑色 
    {
    	b[u]=true; // 标记已经放问过了 
    	if(f)s1++; // 染色 
    	else s2++;
    	for(int v:e[u])
    		if(!b[v])dfs(v,s1,s2,!f); // 进行下一个点的染色,注意 !f 
    }
    int main()
    {
    	int n=in(),m=in();
    	while(m--)
    	{
    		int u=in(),v=in();
    		e[u].push_back(v),e[v].push_back(u); //存 边 
    	}
    	int s1=0,s2=0;
    	for(int i=1;i<=n;i++)
    		if(!b[i]) // 处理每一个联通块 
    		{
    			int ss1=0,ss2=0;
    			dfs(i,ss1,ss2,true); // 这里传入 true 和 false 都可以
    			s1+=min(ss1,ss2),s2+=max(ss1,ss2); // 红蓝最小值和红蓝最大值 
    		}
    	out(s1),putchar(' '),out(s2);
    	return 0;
    }
    
    
    • 1

    信息

    ID
    5629
    时间
    1000ms
    内存
    128MiB
    难度
    (无)
    标签
    递交数
    0
    已通过
    0
    上传者