UVALive-3523 Knights of the Round Table (双连通分量+二分图匹配)
2015-10-20 22:28
465 查看
题目大意:有n个骑士要在圆桌上开会,但是相互憎恶的两个骑士不能相邻,现在已知骑士们之间的憎恶关系,问有几个骑士一定不能参加会议。参会骑士至少有3个且有奇数个。
题目分析:在可以相邻的骑士之间连一条无向边,构成一张图G。则问题变成了有几个节点不在奇圈(有奇数个节点的圈)内,并且一个点在圈内最多出现一次。如果G不连通,应该对每一个分量分别求解。奇圈上的点一定在同一个双连通分量内,要找出所有的双连通分量。但是能构成二分图的双连通分量中一定没有奇圈,不能构成二分图的双连通分量中一定含有奇圈,并且分量中所有的点都在奇圈上,所有还要判断每一个双连通分量能不能构成二分图。
其实就是一道模板题。。。
代码如下:
题目分析:在可以相邻的骑士之间连一条无向边,构成一张图G。则问题变成了有几个节点不在奇圈(有奇数个节点的圈)内,并且一个点在圈内最多出现一次。如果G不连通,应该对每一个分量分别求解。奇圈上的点一定在同一个双连通分量内,要找出所有的双连通分量。但是能构成二分图的双连通分量中一定没有奇圈,不能构成二分图的双连通分量中一定含有奇圈,并且分量中所有的点都在奇圈上,所有还要判断每一个双连通分量能不能构成二分图。
其实就是一道模板题。。。
代码如下:
# include<iostream> # include<cstdio> # include<vector> # include<stack> # include<cstring> # include<algorithm> using namespace std; const int maxn=1005; struct Edge { int u,v; Edge(int _u,int _v):u(_u),v(_v){} }; stack<Edge>S; vector<int>G[maxn],bcc[maxn]; int bcc_cnt,dfs_cnt,low[maxn],pre[maxn],odd[maxn],color[maxn],bccno[maxn],iscut[maxn],A[maxn][maxn]; int dfs(int u,int fa) { int lowu=pre[u]=++dfs_cnt; int child=0; for(int i=0;i<G[u].size();++i){ int v=G[u][i]; if(!pre[v]){ S.push(Edge(u,v)); ++child; int lowv=dfs(v,u); lowu=min(lowu,lowv); if(lowv>=pre[u]){///存在一个满足条件的v,便能说明u是割点。 iscut[u]=1; bcc[++bcc_cnt].clear(); while(1) { Edge x=S.top(); S.pop(); if(bccno[x.u]!=bcc_cnt){ bcc[bcc_cnt].push_back(x.u); bccno[x.u]=bcc_cnt; } if(bccno[x.v]!=bcc_cnt){ bcc[bcc_cnt].push_back(x.v); bccno[x.v]=bcc_cnt; } if(x.u==u&&x.v==v) break; } } } else if(pre[v]<pre[u]&&v!=fa){ S.push(Edge(u,v)); lowu=min(lowu,pre[v]); } } if(fa<0&&child==1)///根节点只有1个子节点时不是割点。 iscut[u]=0; low[u]=lowu; return lowu; } void find_bcc(int n) { memset(pre,0,sizeof(pre)); memset(iscut,0,sizeof(iscut)); memset(bccno,0,sizeof(bccno)); dfs_cnt=bcc_cnt=0; for(int i=0;i<n;++i) if(!pre[i]) dfs(i,-1); } bool bipartite(int u,int b) { for(int i=0;i<G[u].size();++i){ int v=G[u][i]; if(bccno[v]!=b) continue; if(color[v]==color[u]) return false; if(!color[v]){ color[v]=3-color[u]; if(!bipartite(v,b)) return false; } } return true; } int main() { int n,m,a,b; while(scanf("%d%d",&n,&m)&&(n+m)) { memset(A,0,sizeof(A)); for(int i=0;i<n;++i) G[i].clear(); while(m--){ scanf("%d%d",&a,&b); --a,--b; A[a][b]=A[b][a]=1; } for(int i=0;i<n;++i) for(int j=i+1;j<n;++j) if(!A[i][j]) G[i].push_back(j),G[j].push_back(i); find_bcc(n); memset(odd,0,sizeof(odd)); for(int i=1;i<=bcc_cnt;++i){ memset(color,0,sizeof(color)); for(int j=0;j<bcc[i].size();++j) bccno[bcc[i][j]]=i; int u=bcc[i][0]; color[u]=1; if(!bipartite(u,i)) for(int j=0;j<bcc[i].size();++j) odd[bcc[i][j]]=1; } int ans=n; for(int i=0;i<n;++i) if(odd[i]) --ans; printf("%d\n",ans); } return 0; }
相关文章推荐
- JAVA final 、super 关键字以及继承关系中父类与子类实例变量初始化的 理解
- [手游新项目历程]第20天-Wine
- python - 函数参数
- SlidingMenu侧滑菜单栏的使用
- c语言实现,将一个字符串转换为对应的整数
- C++网络通信库性能大比拼
- [笔记]架构探险-从零开始写JavaWeb框架-1. 之搭建轻量级mvc框架
- Tomcat配置优化
- 会计原理与实务
- prototype原型(待完善)
- 计算机图形学基础
- soj2271异或求和
- 在RedHat 6.x和7.x上用编译ffmpeg
- 调试工具BTrace 的使用--例子
- MIT 做了一个全自动的大数据分析系统
- [教程] IDEA13 + Maven 3.1 + Tomcat 7 + jrebel热部署web应用【JRebel无法安装时】
- 在C语言中,double、long、unsigned、int、char类型数据所占字节数
- CSS z-index 属性的使用方法和层级树的概念
- script标签到底该放在哪里
- win8.1+MATLAB安装步骤