知识点:二进制枚举、二分图。
题目链接:https://ac.nowcoder.com/acm/contest/4370/K
题意:给一张图,选择其中任意条边使得不存在奇数长度的环,问最多可以选择几条边。
题解:如果不存在奇数长度的环,那么得到的图为二分图。看到最多只有16个点,所以可以用二进制来枚举上方点集的所有65536种情况即可,输出最大值。
证明:假设存在一个图不是二分图但是不存在奇数长度的环,那么存在一方的点集中有两个点之间有一条边,而若原先这两个点为连通状态,那么一定存在一条偶数路径,所以就构成一个奇数环,与假设矛盾。
AC代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef pair<int,int> pii; 4 vector<pii> edg; 5 bool up[20]; 6 int main(){ 7 int t; 8 cin>>t; 9 for(int cas=1;cas<=t;cas++){ 10 edg.clear(); 11 memset(up,false,sizeof up); 12 int n,m; 13 cin>>n>>m; 14 while(m--){ 15 int u,v; 16 cin>>u>>v; 17 edg.emplace_back(u,v); 18 } 19 int res=0; 20 for(int i=0;i<(1<<n);i++){ 21 for(int j=1;j<=n;j++){ 22 if(i>>(j-1)&1)up[j]=true; 23 else up[j]=false; 24 } 25 int tmp=0; 26 for(auto it:edg){ 27 if(up[it.first]!=up[it.second])tmp++; 28 } 29 res=max(tmp,res); 30 } 31 printf("Case #%d: %d ",cas,res); 32 } 33 return 0; 34 }