1891: 丘比特的烦恼

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的那种)

  1 const
  2     maxn=200200;
  3     maxm=600600;
  4 var
  5     d,first,flag,a:array[0..maxn*2]of longint;
  6     last,next,ans:array[0..maxm*2]of longint;
  7     n,m,p,tot,time:longint;
  8 
  9 procedure insert(x,y:longint);
 10 begin
 11     inc(tot);
 12     last[tot]:=y;
 13     next[tot]:=first[x];
 14     first[x]:=tot;
 15 end;
 16 
 17 function find(x:longint):boolean;
 18 var
 19     i:longint;
 20 begin
 21     i:=first[x];
 22     while i<>0 do
 23       begin
 24         if (flag[last[i]]<>time) and (d[x]+1=d[last[i]]) then
 25         begin
 26           flag[last[i]]:=time;
 27           if (a[last[i]]=0) or (find(a[last[i]])) then
 28           begin
 29             a[last[i]]:=x;
 30             a[x]:=last[i];
 31             exit(true);
 32           end;
 33         end;
 34         i:=next[i];
 35       end;
 36     exit(false);
 37 end;
 38 
 39 var
 40     q:array[0..maxn*2]of longint;
 41 
 42 procedure spfa;
 43 var
 44     i,l,r:longint;
 45 begin
 46     l:=1;
 47     r:=0;
 48     for i:=1 to 2*n do
 49       d[i]:=-1;
 50     for i:=1 to n do
 51       if a[i]=0 then
 52       begin
 53         inc(r);
 54         q[r]:=i;
 55         d[i]:=0;
 56       end;
 57     while l<=r do
 58       begin
 59         if q[l]<=n then
 60           begin
 61             i:=first[q[l]];
 62             while i<>0 do
 63               begin
 64                 if d[last[i]]=-1 then
 65                 begin
 66                   d[last[i]]:=d[q[l]]+1;
 67                   if a[last[i]]>0 then
 68                   begin
 69                     inc(r);
 70                     q[r]:=last[i];
 71                   end;
 72                 end;
 73                 i:=next[i];
 74               end;
 75           end
 76         else
 77           begin
 78             inc(r);
 79             q[r]:=a[q[l]];
 80             d[a[q[l]]]:=d[q[l]]+1;
 81           end;
 82         inc(l);
 83       end;
 84 end;
 85 
 86 procedure init;
 87 var
 88     i,x,y:longint;
 89 begin
 90     read(n,m);
 91     for i:=1 to m do
 92       begin
 93         read(x,y);
 94         insert(x,y+n);
 95         insert(y+n,x);
 96       end;
 97     while p<n do
 98       begin
 99         spfa;
100         inc(time);
101         for i:=1 to n do
102           if a[i]=0 then
103           if find(i) then inc(p);
104       end;
105 end;
106 
107 var
108     dfn,low,c,s:array[0..maxn*2]of longint;
109     cnt,t:longint;
110 
111 function min(x,y:longint):longint;
112 begin
113     if x<y then exit(x);
114     exit(y);
115 end;
116 
117 procedure dfs(x:longint);
118 var
119     i:longint;
120 begin
121     inc(t);
122     dfn[x]:=t;
123     low[x]:=t;
124     flag[x]:=time;
125     inc(tot);
126     s[tot]:=x;
127     i:=first[x];
128     while i<>0 do
129       begin
130         if (a[x]=last[i]) xor (x>n) then
131         begin
132           if dfn[last[i]]=0 then
133             begin
134               dfs(last[i]);
135               low[x]:=min(low[x],low[last[i]]);
136             end
137           else
138             if flag[last[i]]=time then low[x]:=min(low[x],low[last[i]]);
139         end;
140         i:=next[i];
141       end;
142     if dfn[x]=low[x] then
143     begin
144       inc(cnt);
145       while s[tot+1]<>x do
146         begin
147           flag[s[tot]]:=time-1;
148           c[s[tot]]:=cnt;
149           dec(tot);
150         end;
151     end;
152 end;
153 
154 procedure tarjan;
155 var
156     i:longint;
157 begin
158     for i:=1 to n do
159       if dfn[i]=0 then
160       begin
161         inc(time);
162         t:=0;
163         tot:=0;
164         dfs(i);
165       end;
166 end;
167 
168 procedure print;
169 var
170     i,j:longint;
171 begin
172     for i:=1 to n do
173       begin
174         j:=first[i];
175         while j<>0 do
176           begin
177             if c[i]<>c[last[j]] then
178             begin
179               if a[i]=last[j] then ans[(j+1)>>1]:=1
180               else ans[(j+1)>>1]:=2;
181             end;
182             j:=next[j];
183           end;
184       end;
185     for i:=1 to m do
186       write(ans[i]);
187 end;
188 
189 begin
190     init;
191     tarjan;
192     print;
193 end.
View Code
原文地址:https://www.cnblogs.com/Randolph87/p/3756104.html