• bzoj1266


    第一问不谈,

    第二问首先我们要找出哪些是s到t的最短路上的边

    由于是无向图,首先正反两遍最短路,求出是s到任意点的距离,任意点到t的距离(即t到任意点的距离);

    然后穷举每条边判断是否在最短路上用d[x,y]表示x到y的最短路

    则要满足d[s,x]+w(x,y)+d[y,t]=d[s,t],

    然后以代价为流量建图跑最小割即可

    注意每条无向边边要当做两条有向边考虑;

      1 const inf=100000007;
      2 type node=record
      3        from,point,next,flow:longint;
      4      end;
      5 
      6 var edge:array[0..130000] of node;
      7     ans1,ans2:array[0..60010] of longint;
      8     p,cur,pre,numh,h,low,dfn,be,st:array[0..5010] of longint;
      9     tot,d,r,x,y,z,i,j,n,m,s,t,len:longint;
     10     v,f:array[0..5010] of boolean;
     11 
     12 function min(a,b:longint):longint;
     13   begin
     14     if a>b then exit(b) else exit(a);
     15   end;
     16 
     17 procedure add(x,y,f:longint);
     18   begin
     19     inc(len);
     20     edge[len].point:=y;
     21     edge[len].from:=x;
     22     edge[len].flow:=f;
     23     edge[len].next:=p[x];
     24     p[x]:=len;
     25   end;
     26 
     27 procedure sap;
     28   var u,i,j,tmp,neck,q:longint;
     29   begin
     30     u:=s;
     31     numh[0]:=n;
     32     while h[s]<n do
     33     begin
     34       if u=t then
     35       begin
     36         i:=s;
     37         neck:=inf;
     38         while i<>t do
     39         begin
     40           j:=cur[i];
     41           if neck>edge[j].flow then
     42           begin
     43             neck:=edge[j].flow;
     44             q:=i;
     45           end;
     46           i:=edge[j].point;
     47         end;
     48         i:=s;
     49         while i<>t do
     50         begin
     51           j:=cur[i];
     52           dec(edge[j].flow,neck);
     53           inc(edge[j xor 1].flow,neck);
     54           i:=edge[j].point;
     55         end;
     56         u:=q;
     57       end;
     58       q:=-1;
     59       i:=p[u];
     60       while i<>-1 do
     61       begin
     62         j:=edge[i].point;
     63         if (edge[i].flow>0) and (h[u]=h[j]+1) then
     64         begin
     65           q:=i;
     66           break;
     67         end;
     68         i:=edge[i].next;
     69       end;
     70       if q<>-1 then
     71       begin
     72         cur[u]:=q;
     73         pre[j]:=u;
     74         u:=j;
     75       end
     76       else begin
     77         dec(numh[h[u]]);
     78         if numh[h[u]]=0 then exit;
     79         tmp:=n;
     80         i:=p[u];
     81         while i<>-1 do
     82         begin
     83           j:=edge[i].point;
     84           if edge[i].flow>0 then tmp:=min(tmp,h[j]);
     85           i:=edge[i].next;
     86         end;
     87         h[u]:=tmp+1;
     88         inc(numh[h[u]]);
     89         if u<>s then u:=pre[u];
     90       end;
     91     end;
     92   end;
     93 
     94 procedure tarjan(x:longint);
     95   var i,y:longint;
     96   begin
     97     v[x]:=true;
     98     f[x]:=true;
     99     inc(r);
    100     inc(d);
    101     st[r]:=x;
    102     dfn[x]:=d;
    103     low[x]:=d;
    104     i:=p[x];
    105     while i<>-1 do
    106     begin
    107       y:=edge[i].point;
    108       if edge[i].flow>0 then
    109       begin
    110         if not v[y] then
    111         begin
    112           tarjan(y);
    113           low[x]:=min(low[x],low[y]);
    114         end
    115         else if f[y] then
    116           low[x]:=min(low[x],low[y]);
    117       end;
    118       i:=edge[i].next;
    119     end;
    120     if low[x]=dfn[x] then
    121     begin
    122       inc(tot);
    123       while st[r+1]<>x do
    124       begin
    125         y:=st[r];
    126         f[y]:=false;
    127         be[y]:=tot;
    128         dec(r);
    129       end;
    130     end;
    131   end;
    132 
    133 begin
    134   readln(n,m,s,t);
    135   len:=-1;
    136   fillchar(p,sizeof(p),255);
    137   for i:=1 to m do
    138   begin
    139     readln(x,y,z);
    140     add(x,y,z);
    141     add(y,x,0);
    142   end;
    143   sap;
    144   for i:=1 to n do
    145     if not v[i] then
    146     begin
    147       r:=0;
    148       d:=0;
    149       tarjan(i);
    150     end;
    151   i:=0;
    152   while i<=len do
    153   begin
    154     if (edge[i].flow=0) then
    155     begin
    156       x:=edge[i].from;
    157       y:=edge[i].point;
    158       if be[x]<>be[y] then
    159       begin
    160         ans1[i div 2+1]:=1;
    161         if (be[x]=be[s]) and (be[y]=be[t]) or (be[x]=be[t]) and (be[y]=be[s]) then
    162           ans2[i div 2+1]:=1;
    163       end;
    164     end;
    165     i:=i+2;
    166   end;
    167   for i:=1 to m do
    168     writeln(ans1[i],' ',ans2[i]);
    169 end.
    View Code
  • 相关阅读:
    使用jquery插件validate制作的表单验证案例
    POJ2992:Divisors(求N!因子的个数,乘性函数,分解n!的质因子(算是找规律))
    HDU1695:GCD(容斥原理+欧拉函数+质因数分解)好题
    HDU4135Co-prime(容斥原理)
    HDU1796How many integers can you find(容斥原理)
    Miller-Rabin素数测试算法(POJ1811Prime Test)
    乘法逆元+模的运算规则
    因子和与因子个数 (乘性函数)
    费马小定理的证明:
    整数(质因子)分解(Pollard rho大整数分解)
  • 原文地址:https://www.cnblogs.com/phile/p/4473231.html
Copyright © 2020-2023  润新知