BZOJ4874:筐子放球

来源:互联网 发布:程序员退休后怎么办 编辑:程序博客网 时间:2024/05/01 09:28

4874: 筐子放球

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 270  Solved: 191
[Submit][Status][Discuss]

Description

小N最近在研究NP完全问题,小O看小N研究得热火朝天,便给他出了一道这样的题目:
有 n 个球,用整数 1 到 n 编号。还有 m 个筐子,用整数1到m编号。
每个球只能放进特定的两个筐子之一,第 i 个球可以放进的筐子记为 Ai 和 Bi 。
每个球都必须放进一个筐子中。
如果一个筐子内有奇数个球,那么我们称这样的筐子为半空的。
求半空的筐子最少有多少个。
小N看到题目后瞬间没了思路,站在旁边看热闹的小I嘿嘿一笑:"水题!"
然后三言两语道出了一个多项式算法。
小N瞬间就惊呆了,三秒钟后他回过神来一拍桌子:
"不对!这个问题显然是NP完全问题,你算法肯定有错!"
小I浅笑:"所以,等我领图灵奖吧!"
小O只会出题不会做题,所以找到了你--请你对这个问题进行探究,并写一个程序解决此题。

Input

第一行两个整数 n,m
接下来 n 行,第 i + 1 行有两个整数 Ai , Bi ,表示第 i 个球可以放的两个筐子。保证 Ai 不等于 Bi
1 <= n,m <= 2 * 10^5,1 <= Ai,Bi <= m

Output

第一行一个整数表示半空的筐子的最小值。

Sample Input

4 3
1 2
2 3
1 3
1 2

Sample Output

0
1,3 号球都放在 1 号筐子,2,4 号球都放在 2 号筐子。

HINT

各位不妨考虑下,如果要求输出方案应该怎么写.

Source

[Submit][Status][Discuss]

题解:其实我没怎么看懂QAQ  我们把筐子看作点 把求看做边 便可以认为一个具有奇数条边的连通块便是一个答案,听起来很简单吧QAQ
贴上代码:
#include<bits/stdc++.h>#define ll long longconst int INF = 0x7fffffff;const double eps = 1e-5;using namespace std;int read(){int x = 0 , f = 1; char ch = getchar();while(ch<'0'||ch>'9') {if(ch=='-')f*=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+(ch-'0');ch=getchar();}return x * f;}int nedge=0,p[400001],nex[400001],head[400001],n,m;bool b[200001];int sum=0;inline void addedge(int a,int b){    p[++nedge]=b;nex[nedge]=head[a];head[a]=nedge;}void dfs(int x){for(int k = head[x]; k; k = nex[k]){++sum;if(!b[p[k]])b[p[k]]=true,dfs(p[k]);}} int main(){n = read() , m = read();for(int i = 1 ; i <= n ; i++){int x = read() , y = read();addedge(x,y),addedge(y,x);//把第i个球能投进的两个框连起来 }int ans = 0;for(int i = 1 ; i <= m ; i++)if(!b[i]){b[i]=true;sum=0; dfs(i);sum>>=1;if(sum&1) ans++;}printf("%d",ans); }


原创粉丝点击