2019ICPC(上海) - Color Graph(二分图+状态压缩)

题目链接:点击查看

题目大意:给出一个由 n 个点和 m 条边组成的无向图,保证无自环无重边,初始时所有的边都是白色的,现在要求尽可能多的将白边染成红色,不过需要保证不存在红色的奇环,问最多能染多少条边

题目分析:先说题目,读完题后看到不存在奇环,就是二分图的定义了,而数据给的又非常的小,再往状态压缩上想,一来一去不难想到用二进制的 0 和 1 表示二分图的两个部分,枚举每个状态,对于每个状态统计答案,因为每个状态已经限制了,只有原边的两个点在两个部分时才可以建边,所以对于每个状态维护最大值就是答案了,时间复杂度为 m*2^n

别看上面的解析说的简单,上海站的签到题愣是没做出来,水平这么菜今年ICPC还凭什么去和别人争。。一开始读完题确实第一反应是二分图,接着想到的不是状态压缩,而是去找奇环,枚举了很多情况发现不太好找就去开别的题了,最后贡献为 0 ,不对,贡献是别的题目的几发 TLE,还是太菜了啊

代码:

#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<unordered_map>
using namespace std;
     
typedef long long LL;
    
typedef unsigned long long ull;
     
const int inf=0x3f3f3f3f;
     
const int N=300;

int u[N],v[N],vis[N],n,m,ans;

void dfs(int step)
{
	if(step==n+1)
	{
		int cnt=0;
		for(int i=1;i<=m;i++)
			cnt+=vis[u[i]]^vis[v[i]];
		ans=max(ans,cnt);
		return;
	}
	vis[step]=true;
	dfs(step+1);
	vis[step]=false;
	dfs(step+1);
}
 
int main()
{
//#ifndef ONLINE_JUDGE
//  freopen("input.txt","r",stdin);
//    freopen("output.txt","w",stdout);
//#endif
//  ios::sync_with_stdio(false);
    int w;
    cin>>w;
    int kase=0;
    while(w--)
    {
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=m;i++)
    		scanf("%d%d",u+i,v+i);
    	ans=0;
    	dfs(1);
    	printf("Case #%d: %d\n",++kase,ans);
	}
    
	
	
	
	
	
	
	
	
	
	
	
	
	
    return 0;
}
发布了646 篇原创文章 · 获赞 20 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_45458915/article/details/104351268