• ZOJ 2587 最小割


    题意:

    给出一个带权无向图,给出图中a,b两个点,已知切断一每条边都会产生与这条边权值相同的消耗,切断某些边可以使得a,b之间不连通,在已知一个切边方法消耗最小的方法,判断是否存在与此切割方法消耗相同的方法。

    题解:

    判断最小割的唯一性!

    就是老样子从S沿着非满流的正向边遍历点的总数k1,从T沿着非满流的正向边遍历的点的总数k2,若k1+k2=n(总点数)时最小割唯一。

    哎,成了结论了,不会证明。。

    后来又想怎么求最小割的总方案数,也不会。。求大神解释!

    View Code
     1 #include <iostream>
     2 #include <cstdlib>
     3 #include <cstdio>
     4 #include <algorithm>
     5 #include <cstring>
     6 
     7 #define N 1000
     8 #define M 400000
     9 #define INF 1e9
    10 
    11 using namespace std;
    12 
    13 int head[N],to[M],next[M],len[M];
    14 int q[M*4],layer[N];
    15 bool vis[N];
    16 int n,m,S,T,cnt;
    17 
    18 inline void add(int u,int v,int w)
    19 {
    20     to[cnt]=v; len[cnt]=w; next[cnt]=head[u]; head[u]=cnt++;
    21     to[cnt]=u; len[cnt]=0; next[cnt]=head[v]; head[v]=cnt++;
    22 }
    23 
    24 inline void read()
    25 {
    26     memset(head,-1,sizeof head); cnt=0;
    27     memset(vis,0,sizeof vis);
    28     for(int i=1,a,b,c;i<=m;i++)
    29     {
    30         scanf("%d%d%d",&a,&b,&c);
    31         add(a,b,c); add(b,a,c);
    32     }
    33 }
    34 
    35 inline bool bfs()
    36 {
    37     memset(layer,-1,sizeof layer);
    38     int h=1,t=2,sta;
    39     q[1]=S; layer[S]=0;
    40     while(h<t)
    41     {
    42         sta=q[h++];
    43         for(int i=head[sta];~i;i=next[i])
    44             if(len[i]&&layer[to[i]]<0)
    45             {
    46                 layer[to[i]]=layer[sta]+1;
    47                 q[t++]=to[i];
    48             }
    49     }
    50     return layer[T]!=-1;
    51 }
    52 
    53 inline int find(int u,int cur_flow)
    54 {
    55     if(u==T) return cur_flow;
    56     int res=0,tmp;
    57     for(int i=head[u];~i&&res<cur_flow;i=next[i])
    58         if(len[i]&&layer[to[i]]==layer[u]+1)
    59         {
    60             tmp=find(to[i],min(cur_flow-res,len[i]));
    61             len[i]-=tmp; len[i^1]+=tmp; res+=tmp;
    62         }
    63     if(!res) layer[u]=-1;
    64     return res;
    65 }
    66 
    67 inline void dfs1(int u)
    68 {
    69     vis[u]=1;
    70     for(int i=head[u];~i;i=next[i])
    71         if(vis[to[i]]==0&&len[i]>0) dfs1(to[i]);
    72 }
    73 
    74 inline void dfs2(int u)
    75 {
    76     vis[u]=1;
    77     for(int i=head[u];~i;i=next[i])
    78         if(vis[to[i]]==0&&len[i^1]>0) dfs2(to[i]);
    79 }
    80 
    81 inline void go()
    82 {
    83     int ans=0;
    84     while(bfs()) ans+=find(S,INF);
    85     dfs1(S); dfs2(T);
    86     for(int i=1;i<=n;i++)
    87         if(!vis[i]) {puts("AMBIGUOUS");return;}
    88     puts("UNIQUE");
    89 }
    90 
    91 int main()
    92 {
    93     while(scanf("%d%d%d%d",&n,&m,&S,&T)!=EOF)
    94     {
    95         if(n==0&&m==0&&S==0&&T==0) break;
    96         read(),go();
    97     }
    98     return 0;
    99 } 
    没有人能阻止我前进的步伐,除了我自己!
  • 相关阅读:
    【Azure】创建4层SLB运行网站
    【Azure】高可用方案
    【Azure】 微软云资源管理模式(Azure Resource Manager)
    JavaScript BOM
    JavaScript数组的属性和方法
    JavaScript parseFloat() 函数和parseInt()函数
    Javascript实现checkbox的全选
    设计一个含有一个表单的页面,并且在表单上放入一个文本框。编写程序,当鼠标在页面上移动时,鼠标的坐标将显示在这个文本框中。
    如何在页面完全加载后执行JS
    如何让脚本的执行顺序按照你设定的顺序执行
  • 原文地址:https://www.cnblogs.com/proverbs/p/2851968.html
Copyright © 2020-2023  润新知