ZOJ 3316 Game 一般图最大匹配带花树
一般图最大匹配带花树:
建图后,计算最大匹配数.
假设有一个联通块不是完美匹配,先手就能够走那个没被匹配到的点。后手不论怎么走,都必定走到一个被匹配的点上。先手就能够顺着这个交错路走下去,最后一定是后手没有路可走,由于假设还有路可走,这一条交错路,就是一个增广路,必定有更大的匹配.
Game
Time Limit: 1 Second Memory Limit: 32768 KB
Fire and Lam are addicted to the game of Go recently. Go is one of the oldest board games. It is rich in strategy despite its simple rules. The game is played by two players who alternately
place black and white stones on the vacant intersections of a grid of 19*19 lines. Once placed on the board, stones cannot be moved elsewhere, unless they are surrounded and captured by the opponent's stones. The object of the game is to control (surround)
a larger portion of the board than the opponent.
Fire thinks it is too easy for him to beat Lam. So he thinks out a new game to play on the board. There are some stones on the board, and we don't need to care about the stones' color
in this new game. Fire and Lam take turns to remove one of the stones still on the board. But the Manhattan distance between the removed stone and the opponent's last removed stone must not be greater than L. And the one who can't remove any stone
loses the game.
The Manhattan distance between (xi, yi) and (xj, yj) is |xi - xj| + |yi - yj|.
To show the performance of grace, Fire lets Lam play first. In the beginning of the game, Lam can choose to remove any stone on the board.
Fire and Lam are clever, so they both use the best strategy to play this game. Now, Fire wants to know whether he can make sure to win the game.
Input
There are multiple cases (no more than 30).
In each case, the first line is a positive integer n (n <= 361) which indicates the number of stones left on the board. Following are n lines, each contains
a pair of integers x andy (0 <= x, y <= 18), which indicate a stone's location. All pairs are distinct. The last line is an integer L (1 <= L <= 36).
There is a blank line between cases.
Ouput
If Fire can win the game, output "YES"; otherwise, just output "NO".
Sample Input
2
0 2
2 0
2 2
0 2
2 0
4
Sample Output
NO
YES
Author: LIN, Yue
Source: The 10th Zhejiang University Programming Contest
problemId=3726" style="color:blue; text-decoration:none">Submit
Status#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue> using namespace std; const int maxn=500; /*******************************************/ struct Edge
{
int to,next;
}edge[maxn*maxn]; int Adj[maxn],Size; void init()
{
memset(Adj,-1,sizeof(Adj)); Size=0;
} void add_edge(int u,int v)
{
edge[Size].to=v; edge[Size].next=Adj[u]; Adj[u]=Size++;
} /*******************************************/ int n;
int Match[maxn];
int Start,Finish,NewBase;
int Father[maxn],Base[maxn];
bool InQueue[maxn],InPath[maxn],InBlossom[maxn];
int Count;
queue<int> q; int FindCommonAncestor(int u,int v)
{
memset(InPath,false,sizeof(InPath));
while(true)
{
u=Base[u];
InPath[u]=true;
if(u==Start) break;
u=Father[Match[u]];
}
while(true)
{
v=Base[v];
if(InPath[v]) break;
v=Father[Match[v]];
}
return v;
} void ResetTrace(int u)
{
int v;
while(Base[u]!=NewBase)
{
v=Match[u];
InBlossom[Base[u]]=InBlossom[Base[v]]=true;
u=Father[v];
if(Base[u]!=NewBase) Father[u]=v;
}
} void BlossomContract(int u,int v)
{
NewBase=FindCommonAncestor(u,v);
memset(InBlossom,false,sizeof(InBlossom));
ResetTrace(u); ResetTrace(v);
if(Base[u]!=NewBase) Father[u]=v;
if(Base[v]!=NewBase) Father[v]=u;
for(int tu=1;tu<=n;tu++)
{
if(InBlossom[Base[tu]])
{
Base[tu]=NewBase;
if(!InQueue[tu])
{
q.push(tu);
InQueue[tu]=true;
}
}
}
} void FindAugmentingPath()
{
memset(InQueue,false,sizeof(InQueue));
memset(Father,0,sizeof(Father));
for(int i=1;i<=n;i++) Base[i]=i;
while(!q.empty()) q.pop();
q.push(Start); InQueue[Start]=true;
Finish=0; while(!q.empty())
{
int u=q.front(); InQueue[u]=false;
q.pop();
for(int i=Adj[u];~i;i=edge[i].next)
{
int v=edge[i].to;
if(Base[u]!=Base[v]&&Match[u]!=v)
{
if(v==Start||(Match[v]>0&&Father[Match[v]]>0))
BlossomContract(u,v);
else if(Father[v]==0)
{
Father[v]=u;
if(Match[v]>0)
{
q.push(Match[v]);
InQueue[Match[v]]=true;
}
else
{
Finish=v;
return ;
}
}
}
}
}
} void AugmentPath()
{
int u,v,w;
u=Finish;
while(u>0)
{
v=Father[u];
w=Match[v];
Match[v]=u;
Match[u]=v;
u=w;
}
} void Edmonds()
{
memset(Match,0,sizeof(Match));
for(int u=1;u<=n;u++)
{
if(Match[u]==0)
{
Start=u;
FindAugmentingPath();
if(Finish>0) AugmentPath();
}
}
} struct Point
{
int x,y,id;
}p[maxn]; int L; int MHD(Point a,Point b)
{
return abs(a.x-b.x)+abs(a.y-b.y);
} int main()
{
while(scanf("%d",&n)!=EOF)
{
for(int i=1;i<=n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
p[i]=(Point){x,y,i};
}
scanf("%d",&L);
init();
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(i==j) continue;
if(MHD(p[i],p[j])<=L)
{
add_edge(i,j);
add_edge(j,i);
}
}
}
Edmonds();
Count=0;
for(int i=1;i<=n;i++)
{
if(Match[i]) Count++;
else break;
}
//cout<<"--> "<<Count<<endl;
if(Count==n) puts("YES");
else puts("NO");
}
return 0;
}
ZOJ 3316 Game 一般图最大匹配带花树的更多相关文章
- HDOJ 4687 Boke and Tsukkomi 一般图最大匹配带花树+暴力
一般图最大匹配带花树+暴力: 先算最大匹配 C1 在枚举每一条边,去掉和这条边两个端点有关的边.....再跑Edmonds得到匹配C2 假设C2+2==C1则这条边再某个最大匹配中 Boke and ...
- 【learning】一般图最大匹配——带花树
问题描述 对于一个图\(G(V,E)\),当点对集\(S\)满足任意\((u,v)\in S\),均有\(u,v\in V,(u,v)\in E\),且\(S\)中没有点重复出现,我们称\(S\) ...
- UOJ #79 一般图最大匹配 带花树
http://uoj.ac/problem/79 一般图和二分图的区别就是有奇环,带花树是在匈牙利算法的基础上对奇环进行缩点操作,复杂度似乎是O(mn)和匈牙利一样. 具体操作是一个一个点做类似匈牙利 ...
- 【UOJ 79】 一般图最大匹配 (✿带花树开花)
从前一个和谐的班级,所有人都是搞OI的.有 n 个是男生,有 0 个是女生.男生编号分别为 1,…,n. 现在老师想把他们分成若干个两人小组写动态仙人掌,一个人负责搬砖另一个人负责吐槽.每个人至多属于 ...
- 【UOJ #79】一般图最大匹配 带花树模板
http://uoj.ac/problem/79 带花树模板,做法详见cyb的论文或fhq的博客. 带花树每次对一个未盖点bfs增广,遇到奇环就用并查集缩环变成花(一个点),同时记录每个点的Next( ...
- kuangbin带你飞 匹配问题 二分匹配 + 二分图多重匹配 + 二分图最大权匹配 + 一般图匹配带花树
二分匹配:二分图的一些性质 二分图又称作二部图,是图论中的一种特殊模型. 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j ...
- URAL 1099. Work Scheduling (一般图匹配带花树)
1099. Work Scheduling Time limit: 0.5 secondMemory limit: 64 MB There is certain amount of night gua ...
- HDU 4687 Boke and Tsukkomi (一般图匹配带花树)
Boke and Tsukkomi Time Limit: 3000/3000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/Othe ...
- URAL1099 Work Scheduling —— 一般图匹配带花树
题目链接:https://vjudge.net/problem/URAL-1099 1099. Work Scheduling Time limit: 0.5 secondMemory limit: ...
随机推荐
- 微信小程序---代码构成
通过开发者工具快速创建了一个demo项目,观察后可以发现这个项目里边生成了不同类型的文件: .json 后缀的 JSON 配置文件 .wxml 后缀的 WXML 模板文件 .wxss 后缀的 WXSS ...
- Spring-1-IOC
IOC与DI的区别? IOC:控制反转(Inversion of Control是面向对象的一种设计原则,可以用来降低计算机之间的耦合度,其中最常见的是依赖注入).是实现的目标 DI:是实现IOC的一 ...
- 监控java进程是否正常运行
@echo off set _task=java.exe :checkstart for /f "tokens=1" %%n in ('tasklist ^| find " ...
- STL 源码分析六大组件-allocator
1. allocator 基本介绍 分配器(allocator))是C ++标准库的一个组件, 主要用来处理所有给定容器(vector,list,map等)内存的分配和释放.C ++标准库提供了默认使 ...
- Git Bash 常用指令
1. 关于git bash常用指令 推荐博客: 史上最简单的 GitHub 教程 猴子都能懂的GIT入门 Learn Version Control with Git for Free Git Do ...
- linux wget变成000权限
今天使用wget下载文件时出现:-bash: /usr/bin/wget: 权限不够. 查看 /usr/bin/wget 的权限为: ---------- 1 root root 357400 3月 ...
- mybatis动态sql foreach的用法
<select id="findUserByIds" parameterType="com.pojo.QueryVo" resultType=" ...
- LeetCode:不同路径&不同路径II
不同路径一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” ). 机器人每次只能向下或者向右移动一步.机器人试图达到网格的右下角(在下图中标记为“Finish”). 问 ...
- [luoguP1227] [JSOI2008]完美的对称(sort)
传送门 排序! #include <cstdio> #include <iostream> #include <algorithm> #define N 20001 ...
- 洛谷P1021 邮票面值设计
题目描述 给定一个信封,最多只允许粘贴N张邮票,计算在给定K(N+K≤15)种邮票的情况下(假定所有的邮票数量都足够),如何设计邮票的面值,能得到最大值MAX,使在1-MAX之间的每一个邮资值都能得到 ...