zoukankan      html  css  js  c++  java
  • poj1637

    混合图欧拉回路
    首先先明确基本概念
    连通的无向图存在欧拉回路当且仅当不存在奇点
    连通的有向图当且仅当每个点入度=出度
    这道题我们显然应该当作连通的有向图来做
    这个问题的困难之处在于我不知道应该从无向边的什么方向来走
    那我们先假定一个走向,然后就变成了一个完全意义上的有向图,然后我们在进行调整
    假定完方向后,我们就算出每个点的入度出度,
    假如我们调整了了一条无向边的方向,那么对于一个端点入度会+1或-1,出度会-1或+1
    毫无疑问,假如一个点出度和入度和为奇数,那么我永远也无法调整得到这个点出度=入度 
    排除这个情况后,我们考虑将入度>出度的点和入度<出度的点化为两侧
    谈到调整,不难想到最大流的增广路调整,而这题正是用最大流做
    对于每条无向边(u,v),暂定方向为u-->v ,连边u-->v flow=1 (不用管原来的有向边)
    对于入度小于出度的点,从源点连一条到它的边,权值为(out-in)/2;
    出度小于入度的点,连一条它到汇点的权值为(in-out)/2 的边;
    然后我们跑最大流,每次对无向边的调整都对应从源点流1个流量向汇点
    最后我们只要判断源点到各个点是否满流即可,满流就是所有点出度都=入度
    当与源点相连的点(出度>入度的点)都满流后,与汇点相连的点(出度<入度)一定也满流
    因为不管怎么调整,图中总的入度肯定=总的出度

      1 type node=record
      2        next,point,flow:longint;
      3      end;
      4 
      5 var edge:array[0..100010] of node;
      6     d,cur,p,pre,numh,h,cd,rd:array[0..210] of longint;
      7     len,s,t,x,y,z,i,k,n,m:longint;
      8     f:boolean;
      9 
     10 procedure add(x,y,z:longint);
     11   begin
     12     inc(len);
     13     edge[len].point:=y;
     14     edge[len].flow:=z;
     15     edge[len].next:=p[x];
     16     p[x]:=len;
     17   end;
     18 
     19 function min(a,b:longint):longint;
     20   begin
     21     if a>b then exit(b) else exit(a);
     22   end;
     23 
     24 function sap:longint;
     25   var u,i,j,neck,q,tmp:longint;
     26   begin
     27     u:=0;
     28     sap:=0;
     29     fillchar(numh,sizeof(numh),0);
     30     fillchar(h,sizeof(h),0);
     31     numh[0]:=t+1;
     32     for i:=0 to t do
     33       cur[i]:=p[i];
     34     neck:=10010;
     35     while h[0]<t+1 do
     36     begin
     37       i:=cur[u];
     38       d[u]:=neck;
     39       while i<>-1 do
     40       begin
     41         j:=edge[i].point;
     42         if (edge[i].flow>0) and (h[u]=h[j]+1) then
     43         begin
     44           cur[u]:=i;
     45           pre[j]:=u;
     46           u:=j;
     47           neck:=min(edge[i].flow,neck);
     48           if u=t then
     49           begin
     50             sap:=sap+neck;
     51             while u<>0 do
     52             begin
     53               u:=pre[u];
     54               j:=cur[u];
     55               dec(edge[j].flow,neck);
     56               inc(edge[j xor 1].flow,neck);
     57             end;
     58             neck:=10010;
     59           end;
     60           break;
     61         end;
     62         i:=edge[i].next;
     63       end;
     64       if i=-1 then
     65       begin
     66         dec(numh[h[u]]);
     67         if numh[h[u]]=0 then exit;
     68         i:=p[u];
     69         q:=-1;
     70         tmp:=t;
     71         while i<>-1 do
     72         begin
     73           j:=edge[i].point;
     74           if  edge[i].flow>0 then
     75             if h[j]<tmp then
     76             begin
     77               tmp:=h[j];
     78               q:=i;
     79             end;
     80           i:=edge[i].next;
     81         end;
     82         h[u]:=tmp+1;
     83         cur[u]:=q;
     84         inc(numh[h[u]]);
     85         if u<>0 then
     86         begin
     87           u:=pre[u];
     88           neck:=d[u];
     89         end;
     90       end;
     91     end;
     92   end;
     93 
     94 begin
     95   readln(k);
     96   while k>0 do
     97   begin
     98     dec(k);
     99     readln(n,m);
    100     fillchar(p,sizeof(p),255);
    101     fillchar(rd,sizeof(rd),0);
    102     fillchar(cd,sizeof(cd),0);
    103     len:=-1;
    104     for i:=1 to m do
    105     begin
    106       readln(x,y,z);
    107       if x=y then continue;
    108       inc(cd[x]);
    109       inc(rd[y]);
    110       if z=0 then
    111       begin
    112         add(x,y,1);
    113         add(y,x,0);
    114       end;
    115     end;
    116     t:=n+1;
    117     f:=false;
    118     s:=0;
    119     for i:=1 to n do
    120     begin
    121       if (cd[i]+rd[i]) mod 2=1 then
    122       begin
    123         f:=true;
    124         break;
    125       end;
    126       z:=cd[i]-rd[i];
    127       if z>0 then
    128       begin
    129         add(0,i,z div 2);
    130         add(i,0,0);
    131         s:=s+z div 2;
    132       end
    133       else begin
    134         add(i,t,-z div 2);
    135         add(t,i,0);
    136       end;
    137     end;
    138     if f then
    139     begin
    140       writeln('impossible');
    141       continue;
    142     end;
    143     if sap=s then writeln('possible') else writeln('impossible');
    144   end;
    145 end.
    View Code
  • 相关阅读:
    与DSP通信时,RD&WR信号
    4.2.1 Vector bit-select and part-select addressing
    数据校验
    数据结构 (树,图)
    ASOP编译说明
    os
    20180203-增与查
    yum安装MariaDB
    20180202之engine,URL,base,session
    列表
  • 原文地址:https://www.cnblogs.com/phile/p/4473121.html
Copyright © 2011-2022 走看看