zoukankan      html  css  js  c++  java
  • 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 } 
    没有人能阻止我前进的步伐,除了我自己!
  • 相关阅读:
    Code Forces 650 C Table Compression(并查集)
    Code Forces 645B Mischievous Mess Makers
    POJ 3735 Training little cats(矩阵快速幂)
    POJ 3233 Matrix Power Series(矩阵快速幂)
    PAT 1026 Table Tennis (30)
    ZOJ 3609 Modular Inverse
    Java实现 LeetCode 746 使用最小花费爬楼梯(递推)
    Java实现 LeetCode 745 前缀和后缀搜索(使用Hash代替字典树)
    Java实现 LeetCode 745 前缀和后缀搜索(使用Hash代替字典树)
    Java实现 LeetCode 745 前缀和后缀搜索(使用Hash代替字典树)
  • 原文地址:https://www.cnblogs.com/proverbs/p/2851968.html
Copyright © 2011-2022 走看看