博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ1562 NOI2009 变换序列 二分图
阅读量:5132 次
发布时间:2019-06-13

本文共 1276 字,大约阅读时间需要 4 分钟。

题意:给定一个由1-N不重复组成的序列a,再给出N个数的序列b,求是否存在一个序列c,使得任意一个位置i均满足(ai+bi)%N=ci || (ai-bi+N)%N=ci,并求字典序最小的c

题解:

任意一个ai只能变成两个数,所以我们可以建二分图看是否存在完全匹配来确定是否存在合法序列。

由于方案要求字典序最小,因此开邻接表的时候要越小的越在前面,匹配时从N开始匹配。这个比较显然,因为越早匹配完成,之后的点如果产生冲突,一定是先完成匹配的点的匹配点变大。

#include 
#include
#include
#include
#include
#include
using namespace std;const int MAXN=20000+2;const int MAXM=40000+2;struct HASH{ int u; HASH *next; HASH(){} HASH(int _u,HASH *_next):u(_u),next(_next){}}*table[MAXN],mem[MAXM];int N,cnt,markx[MAXN],marky[MAXN];bool flag[MAXN];void Insert(int u,int v){ table[u]=&(mem[cnt++]=HASH(v,table[u]));}bool DFS(int x){ for(HASH *p=table[x];p;p=p->next) if(!flag[p->u]){ flag[p->u]=1; if(marky[p->u]==-1 || DFS(marky[p->u])){ markx[x]=p->u,marky[p->u]=x; return 1; } } return 0;}void Hungary(){ memset(marky,-1,sizeof(marky)); for(int i=N-1;i>=0;i--){ memset(flag,0,sizeof(flag)); if(!DFS(i)){ cout << "No Answer" << endl; exit(0); } }}int main(){ cin >> N; for(int i=1,a,b,D;i<=N;i++){ cin >> D; a=(i-1+D)%N,b=(i-1-D+N)%N; if(a>b) swap(a,b); Insert(i-1,N+b),Insert(i-1,N+a); } Hungary(); for(int i=0;i
View Code

 

转载于:https://www.cnblogs.com/WDZRMPCBIT/p/6481182.html

你可能感兴趣的文章
Eclipse Python插件 PyDev
查看>>
selenium+python3模拟键盘实现粘贴、复制
查看>>
第一篇博客
查看>>
typeof与instanceof的区别
查看>>
网站搭建(一)
查看>>
SDWebImage源码解读之SDWebImageDownloaderOperation
查看>>
elastaticsearch
查看>>
postgreSQL 简单命令操作
查看>>
Spring JDBCTemplate
查看>>
Radon变换——MATLAB
查看>>
第五章笔记
查看>>
Iroha and a Grid AtCoder - 1974(思维水题)
查看>>
gzip
查看>>
转负二进制(个人模版)
查看>>
LintCode-Backpack
查看>>
查询数据库锁
查看>>
[LeetCode] Palindrome Number
查看>>
我对于脚本程序的理解——百度轻应用有感
查看>>
SQL更新某列包含XX的所有值
查看>>
网易味央第二座猪场落户江西 面积超过3300亩
查看>>