博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ1854: [Scoi2010]游戏 二分图
阅读量:6278 次
发布时间:2019-06-22

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

很早之前写的题了,发现没有更博,想了想,更一发出来。

Orz ljss

这是冬令营上的例题...之后,我推出来了一种时间复杂度没有问题,空间复杂度没有问题的方法,额(⊙o⊙)…和给出的正解不同,但是能AC

分析:

正解是什么我忘了,我还是讲一下我自己的方法吧...

首先,这是一个并查集的题...但是,我没有用并查集...之后呢,我当时并不会二分图,也不会匈牙利...之后,我根据臆测...莫名其妙的想到了用二分图+匈牙利算法的方法解决这道题...(这也可以?!)

我们可以这样考虑一下,每个武器有两个属性,那么我们可以连两条边,属性和对应的武器号,顺便,开一个桶处理出每一个属性有多少把武器。

之后呢,枚举答案,对,枚举答案!

枚举答案从1到最大值,判断一下桶中的个数是否为0,如果为0,输出i-1,并且退出程序

如果桶中个数为1,那么说明,如果想要到达这个答案,我们必须使用这把武器的这个属性,那么,我们在对应武器的另一个属性的桶中减去这把武器,即:num[a[i^1]]--;

并且,将这把武器打上标记,下次使用的时候,不能继续使用。

在a[i^1]<a[i]的前提下:

如果num[a[i^1]]减成0,那么答案为i-1,并且退出程序。

如果num[a[i^1]]大于1,那么继续枚举答案。

如果num[a[i^1]]恰好等于1,那么我们递归的继续处理a[i^1]这个属性,处理方法同上。

(手动模拟匈牙利算法,捂脸!!!鬼知道我当时怎么想出来的!!!)

时间复杂度:(可过)

附上代码:

#include 
#include
#include
#include
#include
#include
using namespace std;#define N 1000005#define M 10005int n;int a[N<<1],num[M],u;bool vis[N<<1];struct node{ int to,next;}e[N<<1];int head[M],cnt;void add(int x,int y){ e[cnt].to=y; e[cnt].next=head[x]; head[x]=cnt++; return ;}bool work(int x){ if(num[x]==0&&u>=x)return 0; if(num[x]==1&&u>=x) { for(int i=head[x];i!=-1;i=e[i].next) { int to1=e[i].to; if(!vis[to1]) { num[a[to1^1]]--; vis[to1]=vis[to1^1]=1; if(!work(a[to1^1])) { return 0; }else { return 1; } } } } return 1;}int main(){ memset(head,-1,sizeof(head)); scanf("%d",&n); for(int i=0;i<(n<<1);i++) { scanf("%d",&a[i]); num[a[i]]++; add(a[i],i); } int i; for(i=1;i

  

 

转载于:https://www.cnblogs.com/Winniechen/p/9005270.html

你可能感兴趣的文章
驰骋工作流引擎三种项目集成开发模式
查看>>
SUSE11修改主机名方法
查看>>
jdk6.0 + Tomcat6.0的简单jsp,Servlet,javabean的调试
查看>>
RestTemplate 使用总结
查看>>
Android:apk签名
查看>>
2(2).选择排序_冒泡(双向循环链表)
查看>>
MySQL 索引 BST树、B树、B+树、B*树
查看>>
微信支付
查看>>
CodeBlocks中的OpenGL
查看>>
短址(short URL)
查看>>
C++零基础教程(一)——何谓编程
查看>>
第十三章 RememberMe——《跟我学Shiro》
查看>>
使用rsync的文件和目录排除列表
查看>>
mysql 时间函数 时间戳转为日期
查看>>
索引失效 ORA-01502
查看>>
Oracle取月份,不带前面的0
查看>>
Linux Network Device Name issue
查看>>
IP地址的划分实例解答
查看>>
如何查看Linux命令源码
查看>>
设置 SecureCRT RZ 默认目录
查看>>