1891: 丘比特的烦恼 - BZOJ
2014-05-28 16:21
267 查看
Description
随着社会的不断发展,人与人之间的感情越来越功利化。最近,爱神丘比特发现,爱情也已不再是完全纯洁的了。这使得丘比特很是苦恼,他越来越难找到合适的男女,并向他们射去丘比特之箭。于是丘比特千里迢迢远赴中国,找到了掌管东方人爱情的神——月下老人,向他求教。月下老人告诉丘比特,纯洁的爱情并不是不存在,而是他没有找到。在东方,人们讲究的是缘分。月下老人只要做一男一女两个泥人,在他们之间连上一条红线,那么它们所代表的人就会相爱——无论他们身处何地。而丘比特的爱情之箭只能射中两个距离相当近的人,选择的范围自然就小了很多,不能找到真正的有缘人。丘比特听了月下老人的解释,茅塞顿开,回去之后用了人间的最新科技改造了自己的弓箭,使得丘比特之箭的射程大大增加。这样,射中有缘人的机会也增加了不少。情人节(Valentine's day)的午夜零时,丘比特开始了自己的工作。他选择了男女各N位,感应到他们互相之间是否有缘分。稍稍思考后,他发现恰好可以发现射出N支神箭,使每个人都找到自己的有缘人。正当他为自己的发现兴奋不已,准备射箭时,突然想到,自己只感应了是否有缘分,而没考虑缘分的大小。若是拘泥于射N支神箭,却使得某些有天地良缘的不能终成眷属,或勉强把某些只有猿粪的男女撮合在一起,便不合自己的本意了。但是,把每对男女再感应一次太耗时间,于是丘比特只好求助于你了。 Your Task 告诉你他们之间的缘分,请你找出,在射出N支神箭的前提下,哪些对有缘人一定会在一起,而哪些对有缘人一定会分开。
Input
第一行N M,表示人数与有缘人的对数接下来M行,每行X Y表示第X个男子与第Y个女子有缘分 N<=200000,M<=600000
Output
按输入顺序,对于每对有缘人输出一个数若该对有缘人一定在一起则输出1,若一定分开输出2,否则输出0
Sample Input
3 6
1 1
2 2
3 3
1 2
2 1
3 1
Sample Output
001002
题解:http://blog.csdn.net/pouy94/article/details/6423218
打了好久,终于打出来了
首先我们要求出这个题的一个完备匹配,然后再做第二问(第二问的做法请见bzoj2140: 稳定婚姻)
现在就是要做第一问,n<=200000,m<=600000丧心病狂
但是还是可以做的,因为匈牙利是有优化的就是像dinic一样(虽然我没打过)先标距离标号,然后多路增广,增广时只走标号加1的点(每次多路增广前清空vis数组,多路增广时vis数组不要清空,要不然就不是多路增广,一开始我就错这里了,结果第一个点就超时,不要问我为什么知道,我是不会告诉你我为了测试这个把输出故意搞错,就是一定WA的那种)
View Code
随着社会的不断发展,人与人之间的感情越来越功利化。最近,爱神丘比特发现,爱情也已不再是完全纯洁的了。这使得丘比特很是苦恼,他越来越难找到合适的男女,并向他们射去丘比特之箭。于是丘比特千里迢迢远赴中国,找到了掌管东方人爱情的神——月下老人,向他求教。月下老人告诉丘比特,纯洁的爱情并不是不存在,而是他没有找到。在东方,人们讲究的是缘分。月下老人只要做一男一女两个泥人,在他们之间连上一条红线,那么它们所代表的人就会相爱——无论他们身处何地。而丘比特的爱情之箭只能射中两个距离相当近的人,选择的范围自然就小了很多,不能找到真正的有缘人。丘比特听了月下老人的解释,茅塞顿开,回去之后用了人间的最新科技改造了自己的弓箭,使得丘比特之箭的射程大大增加。这样,射中有缘人的机会也增加了不少。情人节(Valentine's day)的午夜零时,丘比特开始了自己的工作。他选择了男女各N位,感应到他们互相之间是否有缘分。稍稍思考后,他发现恰好可以发现射出N支神箭,使每个人都找到自己的有缘人。正当他为自己的发现兴奋不已,准备射箭时,突然想到,自己只感应了是否有缘分,而没考虑缘分的大小。若是拘泥于射N支神箭,却使得某些有天地良缘的不能终成眷属,或勉强把某些只有猿粪的男女撮合在一起,便不合自己的本意了。但是,把每对男女再感应一次太耗时间,于是丘比特只好求助于你了。 Your Task 告诉你他们之间的缘分,请你找出,在射出N支神箭的前提下,哪些对有缘人一定会在一起,而哪些对有缘人一定会分开。
Input
第一行N M,表示人数与有缘人的对数接下来M行,每行X Y表示第X个男子与第Y个女子有缘分 N<=200000,M<=600000
Output
按输入顺序,对于每对有缘人输出一个数若该对有缘人一定在一起则输出1,若一定分开输出2,否则输出0
Sample Input
3 6
1 1
2 2
3 3
1 2
2 1
3 1
Sample Output
001002
题解:http://blog.csdn.net/pouy94/article/details/6423218
打了好久,终于打出来了
首先我们要求出这个题的一个完备匹配,然后再做第二问(第二问的做法请见bzoj2140: 稳定婚姻)
现在就是要做第一问,n<=200000,m<=600000丧心病狂
但是还是可以做的,因为匈牙利是有优化的就是像dinic一样(虽然我没打过)先标距离标号,然后多路增广,增广时只走标号加1的点(每次多路增广前清空vis数组,多路增广时vis数组不要清空,要不然就不是多路增广,一开始我就错这里了,结果第一个点就超时,不要问我为什么知道,我是不会告诉你我为了测试这个把输出故意搞错,就是一定WA的那种)
const maxn=200200; maxm=600600; var d,first,flag,a:array[0..maxn*2]of longint; last,next,ans:array[0..maxm*2]of longint; n,m,p,tot,time:longint; procedure insert(x,y:longint); begin inc(tot); last[tot]:=y; next[tot]:=first[x]; first[x]:=tot; end; function find(x:longint):boolean; var i:longint; begin i:=first[x]; while i<>0 do begin if (flag[last[i]]<>time) and (d[x]+1=d[last[i]]) then begin flag[last[i]]:=time; if (a[last[i]]=0) or (find(a[last[i]])) then begin a[last[i]]:=x; a[x]:=last[i]; exit(true); end; end; i:=next[i]; end; exit(false); end; var q:array[0..maxn*2]of longint; procedure spfa; var i,l,r:longint; begin l:=1; r:=0; for i:=1 to 2*n do d[i]:=-1; for i:=1 to n do if a[i]=0 then begin inc(r); q[r]:=i; d[i]:=0; end; while l<=r do begin if q[l]<=n then begin i:=first[q[l]]; while i<>0 do begin if d[last[i]]=-1 then begin d[last[i]]:=d[q[l]]+1; if a[last[i]]>0 then begin inc(r); q[r]:=last[i]; end; end; i:=next[i]; end; end else begin inc(r); q[r]:=a[q[l]]; d[a[q[l]]]:=d[q[l]]+1; end; inc(l); end; end; procedure init; var i,x,y:longint; begin read(n,m); for i:=1 to m do begin read(x,y); insert(x,y+n); insert(y+n,x); end; while p<n do begin spfa; inc(time); for i:=1 to n do if a[i]=0 then if find(i) then inc(p); end; end; var dfn,low,c,s:array[0..maxn*2]of longint; cnt,t:longint; function min(x,y:longint):longint; begin if x<y then exit(x); exit(y); end; procedure dfs(x:longint); var i:longint; begin inc(t); dfn[x]:=t; low[x]:=t; flag[x]:=time; inc(tot); s[tot]:=x; i:=first[x]; while i<>0 do begin if (a[x]=last[i]) xor (x>n) then begin if dfn[last[i]]=0 then begin dfs(last[i]); low[x]:=min(low[x],low[last[i]]); end else if flag[last[i]]=time then low[x]:=min(low[x],low[last[i]]); end; i:=next[i]; end; if dfn[x]=low[x] then begin inc(cnt); while s[tot+1]<>x do begin flag[s[tot]]:=time-1; c[s[tot]]:=cnt; dec(tot); end; end; end; procedure tarjan; var i:longint; begin for i:=1 to n do if dfn[i]=0 then begin inc(time); t:=0; tot:=0; dfs(i); end; end; procedure print; var i,j:longint; begin for i:=1 to n do begin j:=first[i]; while j<>0 do begin if c[i]<>c[last[j]] then begin if a[i]=last[j] then ans[(j+1)>>1]:=1 else ans[(j+1)>>1]:=2; end; j:=next[j]; end; end; for i:=1 to m do write(ans[i]); end; begin init; tarjan; print; end.
View Code
相关文章推荐
- BZOJ 2539 [Ctsc2000]丘比特的烦恼 带权二分图的最佳匹配
- [BZOJ2539][Ctsc2000]丘比特的烦恼(KM+计算几何)
- [BZOJ2539][CTSC2000][KM]丘比特的烦恼
- 【BZOJ2539】【codevs1221】丘比特的烦恼,trie树+几何判断+费用流
- [KM算法] BZOJ 2539 [Ctsc2000]丘比特的烦恼
- BZOJ2539: [Ctsc2000]丘比特的烦恼
- bzoj 2539: [Ctsc2000]丘比特的烦恼 (KM算法)
- bzoj1935: [Shoi2007]Tree 园丁的烦恼
- [bzoj1005][HNOI2008]明明的烦恼-Prufer编码+高精度
- bzoj 1005 明明的烦恼 【Prufer序列】
- wikioi 丘比特的烦恼 (最大权匹配)
- BZOJ 1005 [HNOI2008]明明的烦恼
- 【bzoj1005】 HNOI2008—明明的烦恼
- BZOJ.1935.[SHOI2007]Tree园丁的烦恼(CDQ分治 三维偏序)
- BZOJ 1005 [HNOI2008]明明的烦恼 purfer序列,排列组合
- bzoj1005 [HNOI2008]明明的烦恼(prufer序列+组合数学+高精)
- BZOJ 3280: 小R的烦恼 费用流 多路增广
- BZOJ 1005 明明的烦恼 Prufer序列+组合数学+ 暴力分解质因子
- bzoj 1005: [HNOI2008]明明的烦恼(组合数学 purfer sequence)
- 【二分图匹配】【CSTC2000】丘比特的烦恼