//==========================

蒟蒻Macaulish:http://www.cnblogs.com/Macaulish/  转载要声明!

//==========================

判断二分图中某条路是否是唯一的。

网络流做法要加个tarjan

二分图就是再增广看能不能增广

网络流(快但是长)

type
arr=record
toward,next,cap,from:longint;
end;
const
maxn=;
maxm=;
var
edge:array[..maxm]of arr;
first,cur,d,p,gap,num,e,belong,dfn,low:array[..maxn]of longint;
chose:array[..maxn]of boolean;
trie:array[..maxn,'A'..'z'] of longint;
n,esum,s,t,tot,total,peo,time,scc,top:longint; procedure add(j,k,l:longint);
begin
inc(esum);
edge[esum].toward:=k;
edge[esum].next:=first[j];
first[j]:=esum;
edge[esum].from:=j;
edge[esum].cap:=l;
end; procedure addedge(j,k,l:longint);
begin
add(j,k,l);
add(k,j,);
end; function find(ss:string):longint;
var
i,u:longint;
begin
u:=;
for i:= to length(ss) do u:=trie[u][ss[i]];
exit(num[u]);
end; function min(x,y:longint):longint;
begin
if x<y then exit(x);
exit(y);
end; procedure into;
var
i,j,k,m,u,boy,girl:longint;
ss:string;
begin
esum:=-;
tot:=;
total:=;
peo:=;
fillchar(first,sizeof(first),);
readln(n);
s:=n<<+;
t:=n<<+;
tot:=n<<+;
for i:= to n do begin readln(ss);
ss:=ss+' ';
u:=;
j:=;
while (ss[j]<>' ') do begin
if trie[u][ss[j]]= then begin
inc(total);
trie[u][ss[j]]:=total;
end;
u:=trie[u][ss[j]];
inc(j);
end;
inc(peo);
num[u]:=peo;
girl:=peo; inc(j);
u:=;
while (ss[j]<>' ') do begin
if trie[u][ss[j]]= then begin
inc(total);
trie[u][ss[j]]:=total;
end;
u:=trie[u][ss[j]];
inc(j);
end;
inc(peo);
num[u]:=peo;
boy:=peo; e[i]:=esum+;
addedge(girl,boy,);
addedge(s,girl,);
addedge(boy,t,); end;
readln(m);
while m> do begin
dec(m);
readln(ss);
i:=pos(' ',ss);
j:=find(copy(ss,,i-));
k:=find(copy(ss,i+,length(ss)-i));
addedge(j,k,);
end;
end; function sap(x,flow:longint):longint;
var
now,more,i,too:longint;
begin
if x=t then exit(flow);
now:=;
i:=cur[x];
while i>= do begin
too:=edge[i].toward;
if (d[x]=d[too]+) and (edge[i].cap>) then begin
more:=sap(too,min(flow-now,edge[i].cap));
dec(edge[i].cap,more);
inc(edge[i xor ].cap,more);
inc(now,more);
cur[x]:=i;
if flow=now then exit(flow);
end;
i:=edge[i].next;
end;
dec(gap[d[x]]);
if gap[d[x]]= then d[s]:=tot;
inc(d[x]);
inc(gap[d[x]]);
cur[x]:=first[x];
exit(now);
end; procedure maxflow;
var
i:longint;
begin
fillchar(gap,sizeof(gap),);
fillchar(d,sizeof(d),);
gap[]:=tot;
for i:= to tot do cur[i]:=first[i];
while d[s]<tot do sap(s,maxlongint);
end; procedure tarjan(x:longint);
var
i,j,too:longint;
begin
inc(time);
dfn[x]:=time;
low[x]:=time;
inc(top);
p[top]:=x;
chose[x]:=true;
i:=first[x];
while i>= do begin
if edge[i].cap> then begin
too:=edge[i].toward;
if dfn[too]= then begin
tarjan(too);
low[x]:=min(low[x],low[too]);
end
else
if chose[too] then
low[x]:=min(low[x],low[too]);
end;
i:=edge[i].next;
end;
if low[x]=dfn[x] then begin
inc(scc);
repeat
j:=p[top];
dec(top);
chose[j]:=false;
belong[j]:=scc;
until j=x;
end;
end; procedure work;
var
head,tail,i,j,k,l,x,too:longint;
flag:boolean;
begin
time:=;
fillchar(chose,sizeof(chose),false);
fillchar(dfn,sizeof(dfn),);
top:=;
for i:= to tot do
if dfn[i]= then tarjan(i);
for i:= to n do begin
j:=e[i];
k:=edge[j].from;
l:=edge[j].toward;
if (belong[k]=belong[l]) or (edge[j].cap>) then writeln('Unsafe')
else writeln('Safe');
end;
end; begin
into;
maxflow;
work;
end.

匈牙利版

type
arr=record
toward,next,from:longint;
flag:boolean;
end;
const
maxn=;
maxm=;
var
edge:array[..maxm]of arr;
first,cur,d,p,gap,num,e,match,matche:array[..maxn]of longint;
chose:array[..maxn]of boolean;
trie:array[..maxn,'A'..'z'] of longint;
n,esum,s,t,tot,total,peo,time,scc,top:longint; procedure addedge(j,k:longint);
begin
inc(esum);
edge[esum].from:=j;
edge[esum].toward:=k;
edge[esum].next:=first[j];
edge[esum].flag:=true;
first[j]:=esum;
end; function find(ss:string):longint;
var
i,u:longint;
begin
u:=;
for i:= to length(ss) do u:=trie[u][ss[i]];
exit(num[u]);
end; procedure into;
var
i,j,k,m,u,boy,girl:longint;
ss:string;
begin
esum:=;
tot:=;
total:=;
peo:=;
fillchar(first,sizeof(first),);
readln(n);
for i:= to n do begin readln(ss);
ss:=ss+' ';
u:=;
j:=;
while (ss[j]<>' ') do begin
if trie[u][ss[j]]= then begin
inc(total);
trie[u][ss[j]]:=total;
end;
u:=trie[u][ss[j]];
inc(j);
end;
inc(peo);
num[u]:=peo;
girl:=peo; inc(j);
u:=;
while (ss[j]<>' ') do begin
if trie[u][ss[j]]= then begin
inc(total);
trie[u][ss[j]]:=total;
end;
u:=trie[u][ss[j]];
inc(j);
end;
inc(peo);
num[u]:=peo;
boy:=peo; e[i]:=esum+;
addedge(girl,boy); end;
readln(m);
while m> do begin
dec(m);
readln(ss);
i:=pos(' ',ss);
j:=find(copy(ss,,i-));
k:=find(copy(ss,i+,length(ss)-i));
addedge(j,k);
end;
end; function dfs(x:longint):boolean;
var
i,too:longint;
begin
i:=first[x];
while i> do begin
too:=edge[i].toward;
if edge[i].flag and chose[too] then begin
chose[too]:=false;
if (match[too]=) or dfs(match[too]) then begin
edge[matche[too]].flag:=true;
matche[too]:=i;
match[too]:=x;
edge[i].flag:=false;
exit(true);
end;
end;
i:=edge[i].next;
end;
exit(false);
end; procedure work;
var
i,j,boy,girl:longint;
begin
for i:= to n do begin
fillchar(chose,sizeof(chose),true);
dfs(edge[e[i]].from);
end;
//for i:= to n do writeln(match[i<<]);
for i:= to n do begin
fillchar(chose,sizeof(chose),true);
j:=e[i];
if edge[j].flag then begin
writeln('Unsafe');
continue;
end;
boy:=edge[j].toward;
girl:=edge[j].from;
match[boy]:=;
if not dfs(girl) then begin
match[boy]:=girl;
matche[boy]:=j;
writeln('Safe');
end
else writeln('Unsafe');
end;
end; begin
into;
work;
end.

bzoj 2140: 稳定婚姻 (二分图)的更多相关文章

  1. BZOJ 2140 稳定婚姻 ——二分图

    论二分图的可行边与必须边. 考虑用dinic增广之后的图,一些是必要的割边,一些是可行的割边. 我们首先求出一组可行的最大匹配,那么这些变都是可行的. 然后我们求一遍强连通分量. 如果 scc[u]! ...

  2. BZOJ 2140 稳定婚姻

    2140: 稳定婚姻 Description 我国的离婚率连续7年上升,今年的头两季,平均每天有近5000对夫妇离婚,大城市的离婚率上升最快,有研究婚姻问题的专家认为,是与简化离婚手续有关. 25岁的 ...

  3. 2140: 稳定婚姻 - BZOJ

    Description 我国的离婚率连续7年上升,今年的头两季,平均每天有近5000对夫妇离婚,大城市的离婚率上升最快,有研究婚姻问题的专家认为,是与简化离婚手续有关. 25岁的姗姗和男友谈恋爱半年就 ...

  4. 【BZOJ】2140 稳定婚姻

    [解析]Hash,离散化.Tarjan [分析] 对于每一个名字.首先离散化成编号. 用hash或者其它,反正不要最主要的即可了.否则O(N^2L)会爆掉. 然后请參考:http://www.cnbl ...

  5. BZOJ2140: 稳定婚姻

    题解: 题意就是求二分图的必须边. 我们有结论: 在残量网络上跑tarjan,对于一条边(u,v) 如果该边满流||scc[u]==scc[v],那么该边是可行边. 因为如果scc[u]==scc[v ...

  6. BZOJ2140: 稳定婚姻(tarjan解决稳定婚姻问题)

    2140: 稳定婚姻 Time Limit: 2 Sec  Memory Limit: 259 MBSubmit: 1321  Solved: 652[Submit][Status][Discuss] ...

  7. 【稳定婚姻问题】【HDU1435】【Stable Match】

    2015/7/1 19:48 题意:给一个带权二分图  求稳定匹配 稳定的意义是对于某2个匹配,比如,( a ---- 1) ,(b----2) , 如果 (a,2)<(a,1) 且(2,a)& ...

  8. 洛谷 P1407 [国家集训队]稳定婚姻 解题报告

    P1407 [国家集训队]稳定婚姻 题目描述 我国的离婚率连续7年上升,今年的头两季,平均每天有近5000对夫妇离婚,大城市的离婚率上升最快,有研究婚姻问题的专家认为,是与简化离婚手续有关. 25岁的 ...

  9. 【bzoj2140】: 稳定婚姻 图论-tarjan

    [bzoj2140]: 稳定婚姻 哎..都是模板题.. 一眼看过去 哇 二分图哎 然后发现好像并不能匈牙利算法 自己xjb画两张图,发现二分图左向右连配偶的边,然后右向左连交往过的边 然后如果Bi G ...

随机推荐

  1. 如何去除Eclipse下的JS引入报错(类似Syntax error on token...的异常信息)

    在Eclipse下引入外部JS文件,比如Jquery.js,经常会出现如下异常信息: 去除该异常方法: 1. 去掉Eclipse的JS验证 Windws---->Preferences----& ...

  2. TraceHelper

    public class TraceHelper { private static TraceHelper _traceHelper; private TraceHelper() { } public ...

  3. centos7下安装mysql8.0.12及设置权限

    一.mysql版本介绍 mysql的官网为:https://www.mysql.com/ 在官网上可以看到多个版本,主要版本如下, 1.MySQL Community Server 社区版本,开源免费 ...

  4. Android 9 Pie震撼来袭 同步登陆WeTest

    WeTest 导读 2018年8月7日,Google对外发布最新 Android 9.0 正式版系统,并宣布系统版本Android P 被正式命名为代号“Pie”,最新系统已经正式推送包括谷歌Pixe ...

  5. (Python爬虫04)了解通用爬虫和聚焦爬虫,还是理论知识.快速入门可以略过的

    如果现在的你返回N年前去重新学习一门技能,你会咋做? 我会这么干: ...哦,原来这个本事学完可以成为恋爱大神啊, 我要掌握精髓需要这么几个要点一二三四..... 具体的学习步骤是这样的一二三.... ...

  6. 【checkbox-group、checkbox】 多项选择器组件说明

    checkbox-group组件包裹checkbox组件的容器 原型: <check-group bindchange="[EventHandle]"> <che ...

  7. 【movable-area、movable-view】 可移动区域组件说明

    movable-area.movable-view 可移动区域组件 原型: <movable-area scale-area="[Boolean]"> <mova ...

  8. 《Effective C++》读书笔记 资源管理

    C++程序中最常用的资源包括动态分配的内存,文件描述器,互斥锁,数据库连接,网络socket等等.不论哪种资源,重要的是,当你不再使用他时,必须将他归还给系统. 一个很好的做法是以对象管理资源.把资源 ...

  9. springMVC第二章

    springMVC第二章 一.URL 映射 可以同时设置多个URL来访问某个控制器或方法.设置value属性: @RequestMapping(value= {"/grade",& ...

  10. 数独:dfs+剪枝+位运算+排除冗余+优化搜索顺序(未完)

    和蓝桥杯以前一个题一样,但是数据加强了,博主水平有限,没做出来,先在这里记录一下,这里正解,下面是博主的超时做法.最近准备考研,不能深入学习了. 题目描述 数独是一种传统益智游戏,你需要把一个9 × ...