二分图匈牙利也可以

判断必须点就看能不能通过偶数长度的增广路翻过去

代码:

(最后一个点4s多才行,,,卡不过算了)

开始边数写少了RE,应该是4*N*N

M-R随手开了一堆int?都要是long long

// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define il inline
#define reg register int
#define numb (ch^'0')
using namespace std;
typedef long long ll;
il void rd(int &x){
char ch;bool fl=false;
while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
for(x=numb;isdigit(ch=getchar());x=x*+numb);
(fl==true)&&(x=-x);
}
namespace Miracle{
const int N=+;
ll a[N][N];
int co[N*N];
int in[N*N];
int n,m;
struct node{
int nxt,to;
}e[*N*N];
int hd[N*N],cnt;
int num(int x,int y){
return (x-)*m+y;
}
void add(int x,int y){
// cout<<" ahahhaa "<<endl;
e[++cnt].nxt=hd[x];
e[cnt].to=y;
hd[x]=cnt;
}
int to[N*N];
int vis[N*N];
bool dfs(int x,int id){
// cout<<" x "<<x<<" id "<<id<<endl;
for(reg i=hd[x];i;i=e[i].nxt){
int y=e[i].to;
// cout<<" yy "<<y<<" vis "<<vis[y]<<endl;
if(vis[y]==id) continue;
vis[y]=id;
if(!to[y]||dfs(to[y],id)){
to[y]=x;
in[x]=;
to[x]=y;
in[y]=;
return true;
}
}
return false;
}
bool fin(int x,int id,int pos){
if(vis[x]==id) return false;
vis[x]=id;
if(pos==){
if(!to[x]) return true;
return fin(to[x],id,pos^);
}
for(reg i=hd[x];i;i=e[i].nxt){
int y=e[i].to;
if(y!=to[x]){
if(fin(y,id,pos^)) return true;
}
}
return false;
}
ll p[]={,,,,};
ll add(ll x,ll y,ll p){
return x+y>=p?x+y-p:x+y;
}
ll qk(ll x,ll y,ll p){
ll ret=;
while(y){
if(y&) ret=add(ret,x,p);
x=add(x,x,p);
y>>=;
}
return ret;
}
ll qm(ll x,ll y,ll p){
ll ret=;
while(y){
if(y&) ret=qk(ret,x,p);
x=qk(x,x,p);
y>>=;
}
return ret;
}
bool che(ll x,ll d){
int s=;
ll lp=x-;
while(!(lp&)){
++s;lp>>=;
}
ll now=qm(d,lp,x);
if(now==||now==x-) return true;
for(reg i=;i<s;++i){
ll tmp=qk(now,now,x);
if(tmp==&&(now!=&&now!=x-)) return false;
now=tmp;
}
if(now!=) return false;
return true;
}
bool M_R(ll x){
// cout<<" xx "<<x<<endl;
if(x==) return true;
if(x==) return true;
if(x==46856248255981ll) return false;
if(x==||x==||x==||x==||x==||x==||x==||x==||x==||x==||x==) return true;
for(reg i=;i<;++i){
if(x%p[i]==) return false;
if(!che(x,p[i])) return false;
}
// cout<<" ok "<<endl;
return true;
}
int mem[N*N],nb;
int main(){
// cout<<" M_R "<<M_R(1557403521852231)<<endl;
rd(n);rd(m);
// cout<<" 2333 "<<endl;
for(reg i=;i<=n;++i){
for(reg j=;j<=m;++j){
scanf("%lld",&a[i][j]);
co[num(i,j)]=(i+j)%;
}
} // return 0;
for(reg i=;i<=n;++i){
for(reg j=;j<=m;++j){
if(a[i][j]==-) continue;
if(j!=m){
if(a[i][j+]!=-){
if(M_R(a[i][j]+a[i][j+])==){
add(num(i,j),num(i,j+));
add(num(i,j+),num(i,j));
}
}
}
if(i!=n){
if(a[i+][j]!=-){
if(M_R(a[i][j]+a[i+][j])==){
add(num(i,j),num(i+,j));
add(num(i+,j),num(i,j));
// cout<<num(i,j)<<" "<<num(i+1,j)<<endl;
}
}
}
}
}
// cout<<" after build "<<endl;
int tot=;
int le=,ri=;
for(reg i=;i<=n;++i){
for(reg j=;j<=m;++j){
if(co[num(i,j)]==&&a[i][j]!=-){
++le;
tot+=dfs(num(i,j),num(i,j));
}else if(a[i][j]!=-) ++ri;
}
}
// cout<<" le ri "<<le<<" "<<ri<<" tot "<<tot<<endl;
if(le==ri&&tot==le){
puts("");return ;
}
memset(vis,,sizeof vis);
for(reg i=;i<=n;++i){
for(reg j=;j<=m;++j){
if(a[i][j]!=-){
if(!in[num(i,j)]||fin(to[num(i,j)],num(i,j),)){
mem[++nb]=num(i,j);
}
}
}
}
sort(mem+,mem+nb+);
printf("%d\n",nb);
for(reg i=;i<=nb;++i){
printf("%d %d\n",(mem[i]-)/m+,mem[i]-((mem[i]-)/m)*m);
}
return ;
} }
signed main(){
// freopen("data3618.in","r",stdin);
// freopen("data3618.out","w",stdout);
Miracle::main();
return ;
} /*
Author: *Miracle*
Date: 2019/2/2 20:45:23
*/

这个题的二分图匹配思想还是很巧妙

从最大匹配来考虑,便于决策

fzyzojP3618 -- [校内训练-互测20180412]士兵的游戏的更多相关文章

  1. fzyzojP3580 -- [校内训练-互测20180315]小基的高智商测试

    题目还有一个条件是,x>y的y只会出现一次(每个数直接大于它的只有一个) n<=5000 是[HNOI2015]实验比较 的加强版 g(i,j,k)其实可以递推:g(i,j,k)=g(i- ...

  2. 【loj2461】【2018集训队互测Day 1】完美的队列

    #2461. 「2018 集训队互测 Day 1」完美的队列 传送门: https://loj.ac/problem/2461 题解: 直接做可能一次操作加入队列同时会弹出很多数字,无法维护:一个操作 ...

  3. 【2018集训队互测】【XSY3372】取石子

    题目来源:2018集训队互测 Round17 T2 题意: 题解: 显然我是不可能想出来的……但是觉得这题题解太神了就来搬(chao)一下……Orzpyz! 显然不会无解…… 为了方便计算石子个数,在 ...

  4. 【CH 弱省互测 Round #1 】OVOO(可持久化可并堆)

    Description 给定一颗 \(n\) 个点的树,带边权. 你可以选出一个包含 \(1\) 顶点的连通块,连通块的权值为连接块内这些点的边权和. 求一种选法,使得这个选法的权值是所有选法中第 \ ...

  5. 洛谷 P4463 - [集训队互测 2012] calc(多项式)

    题面传送门 & 加强版题面传送门 竟然能独立做出 jxd 互测的题(及其加强版),震撼震撼(((故写题解以祭之 首先由于 \(a_1,a_2,\cdots,a_n\) 互不相同,故可以考虑求出 ...

  6. 6.13校内互测 (DP 带权二分 斜率优化)

    丘中有麻plant 改自这儿,by ZBQ. 还有隐藏的一页不放了.. 直接走下去的话,如果开始时间确定那么到每个点的时间确定,把time减去dis就可以去掉路程的影响了. 这样对于减去d后的t,如果 ...

  7. LOJ3069. 「2019 集训队互测 Day 1」整点计数(min_25筛)

    题目链接 https://loj.ac/problem/3069 题解 复数真神奇. 一句话题意:令 \(f(x)\) 表示以原点 \((0, 0)\) 为圆心,半径为 \(x\) 的圆上的整点数量, ...

  8. Alpha2的项目互评互测

    目录 @(Alpha2项目测试) 这个作业属于哪个课程 课程链接 这个作业要求在哪里 作业要求的链接 团队名称 你的代码我的发 这个作业的目标 其他参考文献 软件测试用例 姓名 学号 团队名称 李涵 ...

  9. [校内训练19_09_10]sort

    题意 给一个非负整数序列,每次问能否异或上一个正整数使得所有的数单调不减.如果能,输出最小的x,否则输出-1.单点修改.多测.要求最多一个log. 思考 只要考虑相邻的两个数.找到这两个数最高的不同的 ...

随机推荐

  1. 如何寻找无序数组中的第K大元素?

    如何寻找无序数组中的第K大元素? 有这样一个算法题:有一个无序数组,要求找出数组中的第K大元素.比如给定的无序数组如下所示: 如果k=6,也就是要寻找第6大的元素,很显然,数组中第一大元素是24,第二 ...

  2. 1042 Shuffling Machine

    一.题目描述 Shuffling is a procedure used to randomize a deck of playing cards. Because standard shufflin ...

  3. 跨域Ajax -- jsonp和cors

    跨域Ajax - jsonp - cors 参考博客: http://www.cnblogs.com/wupeiqi/articles/5703697.html http://www.cnblogs. ...

  4. Xiuno BBS 4.0 修改时间显示

    修罗开源轻论坛程序 - Xiuno BBS 4.0Xiuno BBS 4.0 是一款轻论坛产品,前端基于 BootStrap 4.0.JQuery 3,后端基于 PHP/7 MySQL XCache/ ...

  5. dos2unix命令详解

    基础命令学习目录首页 原文链接:https://blog.csdn.net/leedaning/article/details/53024290 使用git 的时候碰到git将unix换行符转换为wi ...

  6. 浅谈对IT的认识!

    我是一个从农村出来的学生,家里的情况和大多数的农村同学是一样的,家里算不上有钱,父母供我读书,也已经是做到仁至义尽了. 我现在选了,一个和计算机有关的专业---计算机应用技术.就是希望毕业后,可以找到 ...

  7. 结对项目-四则运算出题程序(GUI版)

    目录: 一.致搭档(含项目地址) 二.PSP(planning) 三.结对编程中对接口的设计 四.计算模块接口的设计与实现过程 五.计算模块接口部分的性能改进 六.计算模块部分单元测试展示 七.计算模 ...

  8. linux 环境配置要点

    cd root .bash_profile 这个是配置当前用户的环境变量 cd /etcprofile 这个是配置系统的环境变量 which xxx 查看命令的目录 source .bash_prof ...

  9. By.cssSelector定位元素一个不足发现

     这个如果用cssSelector定位,代码如下,此时输出的数值是0 System.out.println(driver.findElements(By.cssSelector("div[c ...

  10. HDU2883_kebab

    很好的题目. 有不多于200个任务,每个任务要在si到ei这个时间段内完成,每个任务的任务量是ti*ni,只有一台机器,且其单位时间内可完成的任务量为m. 现在问你,能否使所有的任务全部在规定的时间段 ...