• [TD Cup 2014] TDL的YC牌 & TDL的幼儿园


    TDL的YC牌

    传说中的置换群?反正不懂。我的思路竟然是对的,可是为何只有20分?

    (1)尼玛每行数据输出后回车不打!

    (2)写gcd函数脑残把a mod b写成a-b,大大减慢速度…

    (3)看标程才想到用快速幂,第一次知道置换也可以快速幂。

    (4)大小姐啊麻烦你下次看数据范围别把0的个数给数错的……

    果然什么题都要见识一下。跑数据的时候速度仍然堪忧(最后三个点),可能是电脑问题,也可能还能优化?

    program yc;
    const maxn=100000+10;
          q=1e-6;
    var t1,t2,t3,jn,p:int64;
        tt3:real;
        a,b,c,d,base,baset,ans,anst:array[1..maxn] of longint;
        i,t,n,jt,x,k,j:longint;
    function gcd(a,b:int64):integer;
    var t:int64;
    begin
      if b>a then
        begin
          t:=a;a:=b;b:=t;
        end;
      if (a=0) or (b=0) then exit(1);
      if a mod b=0 then gcd:=b else gcd:=gcd(b,a mod b);
    end;
    
    function eq(a:real;b:int64):boolean;
    begin
      if abs(a-b)<=q then exit(true) else exit(false);
    end;
    
    begin
      assign(input,'yc10.in');reset(input);
      assign(output,'yc10.out');rewrite(output);
      readln(t);
      for i:=1 to t do
        begin
          readln(n,t1,t2);
          jn:=1;
          for j:=1 to n do
            read(b[j]);
          for j:=1 to n do
            begin
              jt:=1;x:=b[j];
              while x<>j do
                begin
                  x:=b[x];
                  inc(jt);
                end;
              jn:=jn div gcd(jn,jt) * jt;
            end;
          {for j:=1 to n do a[j]:=j;
          fillchar(jp,sizeof(jp),$7f);
          c:=a;
          for j:=1 to 30 do
            begin
              for k:=1 to n do
                d[k]:=c[b[k]];
              c:=d;
              for k:=1 to n do
                if (a[k]=d[k]) and (k<jp[k]) then jp[k]:=j;
            end;}
          {for j:=1 to n do
            jn:=jn*jt div gcd(jn,jt); }
          for k:=-t2 to t2 do
            begin
              tt3:=(t1+k*jn)/t2;
              if (eq(tt3,round(tt3))) and (tt3>0) then break;
            end;
          t3:=round(tt3);
          for j:=1 to n do
            a[j]:=j;
          for j:=1 to n do ans[j]:=j;
          for j:=1 to n do anst[j]:=j;
          for j:=1 to n do base[j]:=b[j];
          p:=t3;
          while p>0 do
          //for p:=1 to t3 do
            begin
              {for k:=1 to n do
                begin
                  //c[k]:=b[a[k]];
                  c[b[k]]:=a[k];
                end;
              a:=c;
              inc(p);}
              if p mod 2=1 then
                for j:=1 to n do anst[j]:=ans[base[j]];
              ans:=anst;
              for j:=1 to n do baset[j]:=base[base[j]];
              base:=baset;
              p:=p div 2;
            end;
          {for j:=1 to n do
            c[a[j]]:=j;}
          for j:=1 to n do
            write(ans[j],' ');
          writeln;
        end;
      close(input);close(output);
    end.
    yc

    TDL的幼儿园

    昨天又4个人AC,果然我是弱渣,根本看不出这是网络流模型- -!今天学习了Dinic算法,为何感觉比之前写的更简短且容易理解?(咳咳之前那次写的手工栈)

    对题目进行网络流建模,源点(编号0)向每个小朋友连一条边,容量为Ci,所有糖向汇点(编号m+n+1)连一条边,容量为Vi,小朋友和它想要的糖之间连一条容量为inf的边。(要注意inf最好不要设置成maxlongint,否则万一它的flow为负,两者一加就超过范围了,结果坑爹的Lazarus还不报错,传进去一个接近-maxlongint的值,当然这有可能是初始化一开始出错造成的。最后我inf设置成了maxlongint div 2)

    P.S. 题解要不要写的那么暴力啊,一会儿割小朋友,一会儿把它的所有的糖给割掉…

    跟踪了一些变量来搞懂,没有时间把它搞精通了,所以默默地背代码去了。

    话说,我100年没有写链表了!…貌似,这次写的还比较顺…

    程序很大程度参考了http://www.cnblogs.com/htfy/archive/2012/02/15/2353147.html,我没有用静态链表,所以没写xor 1这种办法,用了dec_flow这样一个查找+修改flow的过程。

    一开始跑数据死循环啊!尼玛建边的时候下次注意一点,这次建双向边但是回边的flow是0,不能和去边一样啊 =v=

    program kd2;
    type ptype=^node;
         node=record
                 w,v,flow:longint;
                 next:ptype;
               end;
    const inf=maxlongint div 2;
          maxn=1000;
    var n,m,tar,sta,v,c,x,cn,i,j:longint;
        head:array[0..2*maxn+10] of ptype;
        visit:array[0..2*maxn+10] of boolean;
        d,q:array[0..2*maxn+10] of longint;// distance to st;
    
    function min(a,b:longint):longint;
    begin
      if a<b then exit(a) else exit(b);
    end;
    
    procedure add_edge(st,ed,w:longint);
    var p,q,pre:ptype;
    begin
      new(q);
      q:=head[st];
      new(p);
      p^.w:=w;p^.v:=ed;p^.flow:=0;p^.next:=nil;
      if q=nil then
        begin
          new(head[st]);
          head[st]^:=p^;
        end
      else
        begin
          while q<>nil do
            begin
              pre:=q;
              q:=q^.next;
            end;
          new(q);
          q^:=p^;
          pre^.next:=q;
        end;
    end;
    
    function bfs:boolean;
    var star,rear,x,u:longint;
        y:ptype;
    begin
      fillchar(visit,sizeof(visit),false);
      fillchar(q,sizeof(q),0);
      star:=1;rear:=1;d[sta]:=1;visit[sta]:=true;q[star]:=sta;
      while star<=rear do
        begin
          x:=q[star];
          y:=head[x];
          while y<>nil do
            begin
              if (not visit[y^.v]) and (y^.flow<y^.w) then
                begin
                  visit[y^.v]:=true;
                  d[y^.v]:=d[x]+1;
                  inc(rear);
                  q[rear]:=y^.v;
                end;
              y:=y^.next;
            end;
          inc(star);
        end;
      exit(visit[tar]);
    end;
    
    procedure dec_flow(st,ed,delta:longint);
    var x:ptype;
    begin
      x:=head[st];
      while x^.v<>ed do x:=x^.next;
      x^.flow:=x^.flow-delta;
    end;
    
    function add_flow(p,maxflow:longint):longint;
    var u,o:longint;
        y:ptype;
    begin
      if (p=tar) or (maxflow=0) then exit(maxflow);
      add_flow:=0;
      y:=head[p];
      while y<>nil do
        begin
          if (d[y^.v]=d[p]+1) and (y^.flow<y^.w) then
            begin
              o:=add_flow(y^.v,min(maxflow,y^.w-y^.flow));
              if o>0 then
                begin
                  inc(y^.flow,o);
                  //dec(op_y.flow,o);
                  dec_flow(y^.v,p,o);
                  dec(maxflow,o);inc(add_flow,o);
                  if maxflow=0 then break;
                end;
            end;
          y:=y^.next;
        end;
    end;
    
    function network:longint;
    begin
      network:=0;
      while bfs do
        begin
          inc(network,add_flow(sta,inf));
        end;
    end;
    
    begin
      assign(input,'kd.in');reset(input);
      assign(output,'kd.out');rewrite(output);
      readln(n,m);sta:=0;tar:=m+n+1;
      for i:=1 to m do
        begin
          read(v);
          add_edge(n+i,tar,v);
          add_edge(tar,n+i,0);
        end;
      for i:=1 to n do
        begin
          read(c);
          cn:=cn+c;
          add_edge(sta,i,c);
          add_edge(i,sta,0);
          read(x);
          for j:=1 to x do
            begin
              read(c);
              add_edge(i,n+c,inf);
              add_edge(n+c,i,0);
            end;
          readln;
        end;
      writeln(cn-network);
    end.
    kd
  • 相关阅读:
    LeetCode Path Sum
    实训篇-Html-表单练习
    实训篇-Html-frameset框架集
    实训篇-Html-超链接练习
    实训篇-Html-列表练习
    实训篇-Html-表格练习2
    实训篇-Html-表格练习1
    实训篇-Html-超链接a标签使用
    实训篇-Html-多媒体标签
    实训篇-Html-标题,段落,字体
  • 原文地址:https://www.cnblogs.com/Sky-Grey/p/3835922.html
Copyright © 2020-2023  润新知