HDU - 4619 Warm up 2
来源:互联网 发布:网络层通过什么通信 编辑:程序博客网 时间:2024/05/22 06:18
练习赛打完,看网上的题解都是最大匹配。 。 。 。
思路:
把一个骨牌当成是一条边,两端分别是两个点,然后建图。那么问题就转换成求最多剩下多少条边互不相交。
然后求连通分量,两个连通分量之间不会有边。一个连通分量内,取完后最优的结果一定是每个点都在一条边上(奇数个点会有一个点不在边上),所以有k个点,就会剩下k/2条边。
也就是只需要计算每个连通分量的大小就好。
#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <vector>using namespace std;const int maxn=4000+10;int bcc[maxn];vector<int> G[maxn];int g[111][111];int N, M, n;int cnt, bcc_num[maxn];void dfs(int u, int num){ bcc_num[u]=num; bcc[num]++; for(int i=0; i<G[u].size(); i++) if(!bcc_num[G[u][i]]) dfs(G[u][i], num);}void solve(){ cnt=0; memset(bcc_num, 0, sizeof(bcc_num)); for(int i=1; i<=n; i++) if(!bcc_num[i]) { bcc[++cnt]=0; dfs(i, cnt); } int ans=0; for(int i=1; i<=cnt; i++) ans+=bcc[i]/2; printf("%d\n", ans);}int main(){ while(~scanf("%d%d", &N, &M) && N+M) { memset(g, 0, sizeof(g)); for(int i=0; i<maxn; i++) G[i].clear(); n=0; while(N--) { int x, y, u, v; scanf("%d%d", &x, &y); if(!g[x][y]) { g[x][y]=++n; u=n; } else u=g[x][y]; if(!g[x+1][y]) { g[x+1][y]=++n; v=n; } else v=g[x+1][y]; G[u].push_back(v); G[v].push_back(u); } while(M--) { int x, y, u, v; scanf("%d%d", &x, &y); if(!g[x][y]) { g[x][y]=++n; u=n; } else u=g[x][y]; if(!g[x][y+1]) { g[x][y++]=++n; v=n; } else v=g[x][y+1]; G[u].push_back(v); G[v].push_back(u); } solve(); } return 0;}
0 0
- hdu 4619 Warm up 2
- HDU 4619 Warm up 2
- HDU 4619 Warm up 2
- hdu 4619 Warm up 2
- HDU 4619 Warm up 2
- HDU 4619 Warm up 2
- hdu - 4619 - Warm up 2
- HDU-4619-Warm up 2
- hdu 4619 Warm up 2
- hdu 4619Warm up 2
- HDU 4619 Warm up 2
- HDU - 4619 Warm up 2
- HDU 4619 Warm up 2 解题报告
- hdu 4619 Warm up 2[二分匹配]
- hdu 4619 Warm up 2 (二分匹配)
- hdu 4619 Warm up 2 (二分匹配)
- hdu 4619 Warm up 2(KM)
- hdu 4619 Warm up 2【二分匹配】
- C++中this指针的用法.
- HDU 1846 Brave Game
- 第9周项目1(2)-do while语句
- Lua 与C交互
- 搭建Laravel框架流程
- HDU - 4619 Warm up 2
- R语言学习笔记(三)
- 原生的zfs在rhel6上的安装
- Oracle除去换行符
- R语言学习笔记(四)
- 第九周项目1(3)求1000以内所有偶数的和
- netbeans 中的竖着红线 如何移动
- 今日金融小看
- 第九周上机项目六(2)委派任务