• 839. Optimal Marks


    You are given an undirected graph G(V, E). Each vertex has a mark which is an integer from the range [0..231 – 1]. Different vertexes may have the same mark.

    For an edge (u, v), we define Cost(u, v) = mark[u] xor mark[v].

    Now we know the marks of some certain nodes. You have to determine the marks of other nodes so that the total cost of edges is as small as possible.

    Input

    The first line of the input data contains integer T (1 ≤ T ≤ 10) - the number of testcases. Then the descriptions of T testcases follow.

    First line of each testcase contains 2 integers N and M (0 < N <= 500, 0 <= M <= 3000). N is the number of vertexes and M is the number of edges. Then M lines describing edges follow, each of them contains two integers u, v representing an edge connecting u and v.

    Then an integer K, representing the number of nodes whose mark is known. The next K lines contain 2 integers u and p each, meaning that node u has a mark p. It’s guaranteed that nodes won’t duplicate in this part.

    Output

    For each testcase you should print N lines integer the output. The Kth line contains an integer number representing the mark of node K. If there are several solutions, you have to output the one which minimize the sum of marks. If there are several solutions, just output any of them.

    Example

    Input:
    1
    3 2
    1 2
    2 3
    2
    1 5
    3 100
    
    Output:
    5
    4
    100 
    

    详情请见胡伯涛的论文

    经典最小割模型

    首先我们分位处理,因为每一位都是独立的,互不影响,然后每个点就变成0或1

    再想一下割集的定义,割集把一个图分成了两块,而割集就是这两块之间的连边(好吧,这是我乱编的.....)

    xor正好是值不同才会贡献答案,于是建立最小割模型

    设一个源s,向确定是1的点连容量为inf的边(因为他不能贡献答案,不能让他成为最小割)

    设一个汇t,从确定是0的点向汇连容量为inf的边,理由同上

    其他不确定的点就和所有的点(除了s和t)连容量为1的边(双向都要连)

    然后跑最大流,也就是最小割

    然后我们看这个割集,他把图分成了两部分,最后与s在一起的就是最后为1的(即在残留网络上可以从s走到他),不与s在一起的就是最后为0的,因为是最小割,所以是代价最小的

    然后我们要让总和最小,其实我们已经做到了

    与s在一起的必须是1,可以画图看一看,不与s在一起的不一定选1,为了和最小,就选0

    每一位做一次,最后输出答案就行了

      1 const
      2     maxn=505;
      3     inf=100000;
      4 var
      5     t,si,ti,n,m,step,time:longint;
      6     flag:array[0..maxn]of boolean;
      7     tu:array[0..maxn,0..maxn]of boolean;
      8     map:array[0..maxn,0..maxn]of longint;
      9     a,dis,vh,his,pre,vis:array[0..maxn]of longint;
     10 
     11 procedure sap;
     12 var
     13     i,j,min,aug:longint;
     14     flag:boolean;
     15 begin
     16     fillchar(dis,sizeof(dis),0);
     17     fillchar(vh,sizeof(vh),0);
     18     i:=si;
     19     vh[0]:=n+2;
     20     aug:=inf;
     21     while dis[i]<n+2 do
     22       begin
     23         his[i]:=aug;
     24         flag:=false;
     25         for j:=1 to ti do
     26           if tu[i,j] then
     27           if (map[i,j]>0) and (dis[i]=dis[j]+1) then
     28           begin
     29             if aug>map[i,j] then aug:=map[i,j];
     30             flag:=true;
     31             pre[j]:=i;
     32             i:=j;
     33             if i=ti then
     34             begin
     35               while i<>si do
     36                 begin
     37                   inc(map[i,pre[i]]);
     38                   dec(map[pre[i],i]);
     39                   i:=pre[i];
     40                 end;
     41               aug:=inf;
     42             end;
     43             break;
     44           end;
     45         if flag then continue;
     46         min:=n+1;
     47         for j:=1 to ti do
     48           if tu[i,j] then
     49           if (map[i,j]>0) and (dis[j]<min) then min:=dis[j];
     50         dec(vh[dis[i]]);
     51         if vh[dis[i]]=0 then break;
     52         dis[i]:=min+1;
     53         inc(vh[dis[i]]);
     54         if i<>si then
     55         begin
     56           i:=pre[i];
     57           aug:=his[i];
     58         end;
     59       end;
     60 end;
     61 
     62 procedure dfs(x:longint);
     63 var
     64     i:longint;
     65 begin
     66     vis[x]:=time;
     67     if flag[x]=false then inc(a[x],1<<step);
     68     for i:=1 to ti do
     69       if vis[i]<>time then
     70       if tu[x,i] then
     71       if map[x,i]>0 then dfs(i);
     72 end;
     73 
     74 procedure main;
     75 var
     76     j,k,m,x,y:longint;
     77 begin
     78     fillchar(flag,sizeof(flag),false);
     79     fillchar(tu,sizeof(tu),false);
     80     fillchar(a,sizeof(a),0);
     81     read(n,m);
     82     si:=0;
     83     ti:=n+1;
     84     for j:=1 to m do
     85       begin
     86         read(x,y);
     87         tu[y,x]:=true;
     88         tu[x,y]:=true;
     89       end;
     90     for j:=1 to n do
     91       begin
     92         tu[si,j]:=true;
     93         tu[j,ti]:=true;
     94       end;
     95     read(m);
     96     for j:=1 to m do
     97       begin
     98         read(x,y);
     99         flag[x]:=true;
    100         a[x]:=y;
    101       end;
    102     for step:=0 to 30 do
    103       begin
    104         fillchar(map,sizeof(map),0);
    105         for j:=1 to n do
    106           if flag[j] then
    107             if a[j] and (1<<step)=0 then
    108               begin
    109                 map[j,ti]:=inf;
    110                 for k:=1 to n do
    111                   if flag[k]=false then map[k,j]:=1;
    112               end
    113             else
    114               begin
    115                 map[si,j]:=inf;
    116                 for k:=1 to n do
    117                   if flag[k]=false then map[j,k]:=1;
    118               end
    119           else
    120             for k:=j+1 to n do
    121               if flag[k]=false then
    122               begin
    123                 map[j,k]:=1;
    124                 map[k,j]:=1;
    125               end;
    126         sap;
    127         inc(time);
    128         dfs(0);
    129       end;
    130     for j:=1 to n do
    131       writeln(a[j]);
    132 end;
    133 
    134 begin
    135     read(t);
    136     while t>0 do
    137       begin
    138         main;
    139         dec(t);
    140       end;
    141 end.
    View Code
  • 相关阅读:
    微信开发 接口测试
    微信开发 消息接口
    java微信学习 接入
    排序算法 java实现2
    排序算法 java实现
    第一篇博客
    Android——反编译持续完善
    Android——实用小技巧
    Android——网络编程
    Android——服务
  • 原文地址:https://www.cnblogs.com/Randolph87/p/3629214.html
Copyright © 2020-2023  润新知