匈牙利(大视野1191,1854)

http://www.lydsy.com/JudgeOnline/problem.php?id=1191

主持人问题准备了若干道题目,只有当选手正确回答一道题后,才能进入下一题,否则就被淘汰。为了增加节目的趣味性并适当降低难度,主持人总提供给选手几个“锦囊妙计” 这里,我们把规则稍微改变一下。假设主持人总共有m道题,选手有n种不同的“锦囊妙计”。主持人规定,每道题都可以从两种“锦囊妙计”中选择一种,而每种“锦囊妙计”只能用一次。我们又假设一道题使用了它允许的锦囊妙计后,就一定能正确回答,顺利进入下一题。现在我来到了节目现场,可是我实在是太笨了,每道题只好借助使用“锦囊妙计”来通过。如果我事先就知道了每道题能够使用哪两种“锦囊妙计”,那么你能告诉我怎样选择才能通过最多的题数吗?
Input
输入文件的一行是两个正整数n和m(0 < n <1001,0 < m < 1001)表示总共有n中“锦囊妙计”,编号为0~n-1,总共有m个问题。
以下的m行,每行两个数,分别表示第m个问题可以使用的“锦囊妙计”的编号。
注意,每种编号的“锦囊妙计”只能使用一次,同一个问题的两个“锦囊妙计”可能一样。
Output
第一行为最多能通过的题数p
Sample Input
5 6
3 2
2 0
0 3
0 4
3 2
3 2
Sample Output
4

可以理解为一个二分图;求从1开始不间断的最大匹配
可以用匈牙利来解决
如果ab边可以连或原来连着b的人可以连别的边就将ab连上
直到连不上为止。

var a:array[0..1000,0..1000] of longint;
    i,j,k,l,m,n,q,w:longint;
    b,c:array[0..1000] of boolean;
    d:array[0..1100] of longint;
function cz(p:longint):boolean;
var i,j:longint;
begin
    for i:=0 to n-1 do 
        if (a[p,i]<>0)and(b[i]=false)then begin
              b[i]:=true;
                  if(d[i]=0)or(cz(d[i]))then begin
                      d[i]:=p;exit(true);
                  end;
              end;
     exit(false);
end;
begin
    readln(n,m);
    for i:=1 to m do begin
        readln(k,l);
        a[i,k]:=1;a[i,l]:=1;
    end;
    for i:=1 to m do begin
        fillchar(b,sizeof(b),false);
        if cz(i)=true then inc(q)else break;
    end;
    writeln(q);
end.

1854

lxhgww最近迷上了一款游戏,在游戏里,他拥有很多的装备,每种装备都有2个属性,这些属性的值用[1,10000]之间的数表示。当他使用某种装备时,他只能使用该装备的某一个属性。并且每种装备最多只能使用一次。 游戏进行到最后,lxhgww遇到了终极boss,这个终极boss很奇怪,攻击他的装备所使用的属性值必须从1开始连续递增地攻击,才能对boss产生伤害。也就是说一开始的时候,lxhgww只能使用某个属性值为1的装备攻击boss,然后只能使用某个属性值为2的装备攻击boss,然后只能使用某个属性值为3的装备攻击boss……以此类推。 现在lxhgww想知道他最多能连续攻击boss多少次?
输入的第一行是一个整数N,表示lxhgww拥有N种装备 接下来N行,是对这N种装备的描述,每行2个数字,表示第i种装备的2个属性值
输出一行,包括1个数字,表示lxhgww最多能连续攻击的次数。
样例输入
3
1 2
3 2
4 5
样例输出
2
【数据范围】
对于30%的数据,保证N < =1000
对于100%的数据,保证N < =1000000

将属性视为题目,将装备视为锦囊
因为fillchar 太慢 记录每个点是否用过的数组只对当前i起作用
所以可以使用时间戳代替
上代码

var a1,a2,a3,b,c,ne,d:array[1..2000000] of longint;
    i,j,k,l,m,n,q,w,t:longint;
procedure ad(p,o:longint);
begin
    t:=t+1;a1[t]:=p;a2[t]:=o;ne[t]:=c[p];c[p]:=t;
end;
function cz(p:longint):boolean;
var i:longint;
begin
i:=c[p];
    while i<>0 do begin
        if(***b[a2[i]]<>j***)then begin b[a2[i]]:=j;
                  if(d[a2[i]]=0)or(cz(d[a2[i]]))then begin
                      d[a2[i]]:=p; exit(true);
                  end;
              end;
              i:=ne[i];
        end;
        exit(false);
end;
begin
    readln(n);
    for i:=1 to n do begin
        readln(k,l);
        ad(k,i); ad(l,i);
        if m<k then m:=k;
        if m<l then m:=l;
    end;
    for *j*:=1 to m do begin
        if cz(j) then q:=q+1 else break;
    end;
    writeln(q);
end.
先展示下效果 https://pan.quark.cn/s/a4b39357ea24 遗传算法 - 简书 遗传算法的理论是根据达尔文进化论而设计出来的算法: 人类是朝着好的方向(最优解)进化,进化过程中,会自动选择优良基因,淘汰劣等基因。 遗传算法(英语:genetic algorithm (GA) )是计算数学中用于解决最佳化的搜索算法,是进化算法的一种。 进化算法最初是借鉴了进化生物学中的一些现象而发展起来的,这些现象包括遗传、突变、自然选择、杂交等。 搜索算法的共同特征为: 首先组成一组候选解 依据某些适应性条件测算这些候选解的适应度 根据适应度保留某些候选解,放弃其他候选解 对保留的候选解进行某些操作,生成新的候选解 遗传算法流程 遗传算法的一般步骤 my_fitness函数 评估每条染色体所对应个体的适应度 升序排列适应度评估值,选出 前 parent_number 个 个体作为 待选 parent 种群(适应度函数的值越小越好) 从 待选 parent 种群 中随机选择 2 个个体作为父方和母方。 抽取父母双方的染色体,进行交叉,产生 2 个子代。 (交叉概率) 对子代(parent + 生成的 child)的染色体进行变异。 (变异概率) 重复3,4,5步骤,直到新种群(parentnumber + childnumber)的产生。 循环以上步骤直至找到满意的解。 名词解释 交叉概率:两个个体进行交配的概率。 例如,交配概率为0.8,则80%的“夫妻”会生育后代。 变异概率:所有的基因中发生变异的占总体的比例。 GA函数 适应度函数 适应度函数由解决的问题决定。 举一个平方和的例子。 简单的平方和问题 求函数的最小值,其中每个变量的取值区间都是 [-1, ...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值