NPC,即Non_Player Character,作为游戏很重要的一种存在……

哎不对,扯远了。

这题出题人卖萌,明显不是NPC问题。

我们可以发现(通过前几个点找一找规律什么的)这题可以建立一个一般图最大匹配模型。

首先将所有的筐子拆成3个点,任选其中两点连边,然后对于每一个条件,将对应球与筐子的三个点分别连边。

可以证明(不会),最大匹配中所有球一定是匹配了的。

于是就可以用带花树(没学过)求解一般图最大匹配了。

复杂度O(VE),和二分图最大匹配一样

代码写挫了,跑了78MS。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=600+5;
struct Edge{int to,next;}e[N*N];
int head[N],cnt;
void ins(int u,int v){e[++cnt]=(Edge){v,head[u]};head[u]=cnt;
}
void insert(int u,int v){ins(u,v);ins(v,u);
}
int pa[N];
int find(int x){return pa[x]==x?x:pa[x]=find(pa[x]);
}
void merge(int u,int v){u=find(u);v=find(v);if(u!=v)pa[u]=v;
}
int n,linked[N],next[N],que[N],front,rear,mark[N],vis[N];
int lca(int u,int v){static int T=0;T++;while(true){while(u!=-1){u=find(u);if(vis[u]==T)return u;vis[u]=T;if(linked[u]!=-1)u=next[linked[u]];else u=-1;}swap(u,v);}
}
void blossom(int a,int t){while(a!=t){int b=linked[a],c=next[b];if(find(c)!=t)next[c]=b;if(mark[b]==2)mark[que[++rear]=b]=1;if(mark[c]==2)mark[que[++rear]=c]=1;merge(a,b);merge(b,c);a=c;}
}
void aug(int s){for(int i=1;i<=n;i++)next[i]=vis[i]=-1,mark[i]=0,pa[i]=i;mark[s]=1;que[rear=0]=s;for(front=0;linked[s]==-1&&front<=rear;front++){int u=que[front];for(int i=head[u];i;i=e[i].next){int v=e[i].to;if(linked[u]==v||find(u)==find(v)||mark[v]==2)continue;if(mark[v]==1){int w=lca(u,v);if(find(u)!=w)next[u]=v;if(find(v)!=w)next[v]=u;blossom(u,w);blossom(v,w);}else if(linked[v]==-1){next[v]=u;for(u=v;u!=-1;){v=next[u];int tmp=linked[v];linked[u]=v;linked[v]=u;u=tmp;}break;}else{next[v]=u;mark[que[++rear]=linked[v]]=1;mark[v]=2;}}}
}
int sz,node[105][3],belong[N];
int main(){int cas;scanf("%d",&cas);while(cas--){int a,b,c;scanf("%d%d%d",&a,&b,&c);memset(head,0,sizeof(head));cnt=0;sz=a;for(int i=1;i<=b;i++){node[i][0]=++sz;belong[sz]=i;node[i][1]=++sz;belong[sz]=i;node[i][2]=++sz;belong[sz]=i;insert(node[i][0],node[i][1]);}n=sz;for(int i=1;i<=c;i++){int u,v;scanf("%d%d",&u,&v);for(int j=0;j<3;j++)insert(u,node[v][j]);}memset(linked,-1,sizeof(linked));for(int i=1;i<=n;i++)if(linked[i]==-1)aug(i);int ans=0;for(int i=1;i<=n;i++)if(linked[i]!=-1)ans++;printf("%d\n",ans/2-a);for(int i=1;i<=a;i++)printf("%d ",belong[linked[i]]);putchar('\n');}return 0;
}

才过了一个月发现带花树这东西感觉跟没学过一样啊TAT,蒟蒻表示有点方。

然而这题总不能就这么不会了吧,于是从论文里学了一种特殊的玩泥巴技巧

大概就是随机化+匈牙利,最好战绩水到了80分QAQ,果然数据是特殊构造的。。。。

有两个点T了,感觉时间宽一点大概就A了吧。

顺便说这个代码A掉了模板题库里的一般图最大匹配,这时候应该有老司机来hack我。。。。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<ctime>
using namespace std;
const int N=600+5;
bool g[N][N];
bool vis[N];
int linked[N],p[N],q[N],n,anslink[N],ans;
int ba,bl;
void ins(int u,int v){g[u][v]=g[v][u]=1;
}
bool match(int u){vis[u]=1;for(int i=1;i<=n;i++){int v=q[i];if(vis[v]||!g[u][v])continue;vis[v]=1;if(!linked[v]||match(linked[v])){linked[v]=u;linked[u]=v;return true;}}return false;
}
void update(int tmp){ans=tmp;for(int i=1;i<=ba;i++)anslink[i]=linked[i];
}
void work(){memset(linked,0,sizeof(linked));int tmp=0;for(int i=1;i<=n;i++)if(!linked[p[i]])for(int t=1;t<=10;t++){memset(vis,0,sizeof(vis));if(match(p[i])){tmp++;break;}else{for(int j=1;j<=n;j++){int k=j+rand()%(n-j+1);swap(q[j],q[k]);}}}if(tmp>ans)update(tmp);
}
int b1(int i){return ba+i;
}
int b2(int i){return ba+bl+i;
}
int b3(int i){return ba+bl+bl+i;
}
int calc(int x){if(x<=ba+bl)return x-ba;if(x<=ba+bl+bl)return x-ba-bl;return x-ba-bl-bl;
}
int main(){//freopen("a.in","r",stdin);int T;scanf("%d",&T);srand(541213);while(T--){int e;scanf("%d%d%d",&ba,&bl,&e);memset(g,0,sizeof(g));for(int i=1;i<=bl;i++)ins(b1(i),b2(i));n=ba+bl*3;int a,b;while(e--){scanf("%d%d",&a,&b);ins(a,b1(b));ins(a,b2(b));ins(a,b3(b));}ans=0;for(int i=1;i<=n;i++)p[i]=q[i]=i;for(int k=1;k<=10;k++){for(int i=1;i<=ba;i++){int j=i+rand()%(ba-i+1);swap(p[i],p[j]);}for(int i=1;i<=n;i++){int j=i+rand()%(n-i+1);swap(q[i],q[j]);}work();}printf("%d\n",ans-ba);for(int i=1;i<=ba;i++)printf("%d ",calc(anslink[i]));putchar('\n');}return 0;
}

WC2016 挑战NPC相关推荐

  1. luogu P4258 [WC2016]挑战NPC(一般图的最大匹配,带花树,建图、拆点技巧)

    整理的算法模板合集: ACM模板 luogu P4258 [WC2016]挑战NPC 如果是一堆球一堆筐,每一个筐里只能放一个球,求最大能放多少个球, 那么就是一个二分图的最大匹配问题,非常简单,我们 ...

  2. 【BZOJ4405】【WC2016】挑战NPC(带花树)

    [BZOJ4405][WC2016]挑战NPC(带花树) 题面 BZOJ 洛谷 Uoj Description 小N最近在研究NP完全问题,小O看小N研究得热火朝天,便给他出了一道这样的题目: 有n个 ...

  3. 【WC2016】挑战NPC 【带花树】【建图】

    传送门 题意:有nnn个球和mmm个筐,每个筐最多放333个球,每个球只能放入特定的一些筐中,在题中给出.构造一种放球的方案使得nnn个球都被放在某个筐中且 球的个数不超过111 的筐的数量尽量大. ...

  4. 挑战NPC(洛谷-P4258)

    题目描述 小 N 最近在研究 NP 完全问题,小 O 看小 N 研究得热火朝天,便给他出了一道这样的题目: 有 n 个球,用整数 1 到 n 编号.还有 m 个筐子,用整数 1 到 m 编号.每个筐子 ...

  5. P4258-[WC2016]挑战NPC【带花树】

    正题 题目链接:https://www.luogu.com.cn/problem/P4258 题目大意 给出nnn个球,mmm个篮筐,每个球都可以被放入一些特定的篮筐,每个球都要放,要求球的个数小于等 ...

  6. Noip前的大抱佛脚----赛前任务

    赛前任务 tags:任务清单 前言 现在xzy太弱了,而且他最近越来越弱了,天天被爆踩,天天被爆踩 题单不会在作业部落发布,所以可(yi)能(ding)会不及时更新 省选前的练习莫名其妙地成为了Noi ...

  7. 牛客2021年七夕节比赛 F 清楚姐姐的翅膀们【带花树】

    传送门 清 楚 姐 姐 的 后 宫 有 很 多 妹 子 , 她 们 都 是 清 楚 姐 姐 的 翅 膀 . 当时觉得是匹配,就狂交了六十多发随机 题意: N N N个妹子, M M M个蝴蝶结 每个蝴 ...

  8. 图论 —— 带花树算法

    [概述] 带花树算法用于解决一般图的最大匹配问题. 对于一个图 G(V,E),他的匹配 M 是二元组 (u,v) 组成的集合,其中 u,v∈V,(u,b)∈E,且 M 中不存在重复的点,当 |M| 最 ...

  9. WC酱油记——博客一个月没更新留念

    不知不觉一月就这么过去了,估计二月也会很快的谜之消失吧.. 博客一直也没有更新,CF的题也是坑着一坨,考试考的我身败名裂然后还要去参加WC被虐... 总之一下就回忆一下我的WC日常吧..但是因为我是隔 ...

最新文章

  1. 尺取法——POJ3061
  2. C# 填充pdf 模板生成报告
  3. 删除所有的.svn文件夹
  4. 在reader中勾选pdf复选框_绝对可勾选的在WORD 2003中加入复选框的方法
  5. IMOAutocompletionViewController
  6. python三级联动菜单_详解element-ui级联菜单(城市三级联动菜单)和回显问题
  7. JAVA模拟HTTP post请求上传图片
  8. c语言中如何将select出来的字段值赋给一个变量,sql server 重命名列(字段)
  9. How to Visualize Your Recurrent Neural Network with Attention in Keras
  10. (MoMoCMS教程11)页面的SEO优化与外链
  11. 链接器工具错误 LNK2019 必须在友元声明中显式指定模板参数
  12. Python实现PLA(感知机)
  13. 全国计算机二级c语言答案,全国计算机二级C语言试题及答案
  14. Java时间与日期类(Calendar类的方法应用与打印日历)
  15. c语言图书管理系统用什么软件,编写c语言的软件 纯C语言编写图书管理系统.doc...
  16. qt、adb、小米屏幕滑动demo
  17. python爬取网易云音乐飙升榜音乐_python爬取网易云音乐热歌榜实例代码
  18. NOI 2005 题解
  19. 智能交通行业车车通信和车路通信成为ITS下一个技术亮点
  20. 欧卡2在线服务器返回数据错误,omsi2开启时报错是怎么回事

热门文章

  1. 【SQL Server】已更新或删除的行值要么不能使该行成为唯一行,要么改变了多个行 问题解决
  2. Auto CAD中“旋转”命令怎么使用?
  3. bugly android 错误不上报,Bugly不上上报日志的解决办法
  4. ppt怎么把图片做成翻书效果_ppt怎么做出翻页效果图文教程
  5. 分布式缓存(Redis)连杀
  6. 任买分期搞了个“斩男春计划” 我从中看到了消费分期成功的秘诀
  7. Xcode怎么退回旧版本?
  8. HTML标签之常见格式标签(1)
  9. 创新朋友圈植入广告,享受精准的朋友圈营销
  10. Ngnix+Tomcat配置负载均衡