• bzoj4519 [Cqoi2016]不同的最小割


    Description

    学过图论的同学都知道最小割的概念:对于一个图,某个对图中结点的划分将图中所有结点分成两个部分,如果结点s,t不在同一个部分中,则称这个划分是关于s,t的割。对于带权图来说,将所有顶点处在不同部分的边的权值相加所得到的值定义为这个割的容量,而s,t的最小割指的是在关于s,t的割中容量最小的割。
    而对冲刺NOI竞赛的选手而言,求带权图中两点的最小割已经不是什么难事了。我们可以把视野放宽,考虑有N个点的无向连通图中所有点对的最小割的容量,共能得到N(N−1)2个数值。
    这些数值中互不相同的有多少个呢?这似乎是个有趣的问题。

    Input

    输入文件第一行包含两个数N,M,表示点数和边数。接下来M行,每行三个数u,v,w,
    表示点u和点v(从1开始标号)之间有条边权值是w。
    1<=N<=850 1<=M<=8500 1<=W<=100000

    Output

     输出文件第一行为一个整数,表示个数。

    Sample Input

    4 4
    1 2 3
    1 3 6
    2 4 5
    3 4 4

    Sample Output

    3

    正解:最小割树。

    $ZJOI2011$最小割的双倍经验题。。具体做法详见前一篇博客。

      1 //It is made by wfj_2048~
      2 #include <algorithm>
      3 #include <iostream>
      4 #include <complex>
      5 #include <cstring>
      6 #include <cstdlib>
      7 #include <cstdio>
      8 #include <vector>
      9 #include <cmath>
     10 #include <queue>
     11 #include <stack>
     12 #include <map>
     13 #include <set>
     14 #define inf (1<<30)
     15 #define N (1010)
     16 #define il inline
     17 #define RG register
     18 #define ll long long
     19 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
     20 
     21 using namespace std;
     22 
     23 struct edge{ int nt,to,flow,cap; }g[1000010];
     24 
     25 int head[N],vis[N],tmp[N],id[N],d[N],q[N],st[N*N],ans[N][N],Q,n,m,num,cnt,top,Ans;
     26 
     27 il int gi(){
     28     RG int x=0,q=1; RG char ch=getchar();
     29     while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
     30     if (ch=='-') q=-1,ch=getchar();
     31     while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
     32     return q*x;
     33 }
     34 
     35 il void insert(RG int from,RG int to,RG int cap){
     36     g[++num]=(edge){head[from],to,0,cap},head[from]=num; return;
     37 }
     38 
     39 il int bfs(RG int S,RG int T){
     40     memset(d,0,sizeof(d));
     41     RG int h=0,t=1; q[t]=S,d[S]=1;
     42     while (h<t){
     43     RG int x=q[++h],v;
     44     for (RG int i=head[x];i;i=g[i].nt){
     45         v=g[i].to;
     46         if (!d[v] && g[i].cap>g[i].flow){
     47         d[v]=d[x]+1,q[++t]=v;
     48         if (v==T) return 1;
     49         }
     50     }
     51     }
     52     return 0;
     53 }
     54 
     55 il int dfs(RG int x,RG int T,RG int a){
     56     if (x==T || !a) return a; RG int flow=0,f,v;
     57     for (RG int i=head[x];i;i=g[i].nt){
     58     v=g[i].to;
     59     if (d[v]==d[x]+1 && g[i].cap>g[i].flow){
     60         f=dfs(v,T,min(a,g[i].cap-g[i].flow));
     61         if (!f){ d[v]=-1; continue; }
     62         g[i].flow+=f,g[i^1].flow-=f;
     63         flow+=f,a-=f; if (!a) return flow;
     64     }
     65     }
     66     return flow;
     67 }
     68 
     69 il int maxflow(RG int S,RG int T){
     70     RG int flow=0;
     71     while (bfs(S,T)) flow+=dfs(S,T,inf);
     72     return flow;
     73 }
     74 
     75 il void Dfs(RG int x){
     76     vis[x]=cnt;
     77     for (RG int i=head[x];i;i=g[i].nt)
     78     if (g[i].cap>g[i].flow && vis[g[i].to]!=cnt) Dfs(g[i].to);
     79     return;
     80 }
     81 
     82 il void solve(RG int L,RG int R){
     83     if (L==R) return;
     84     for (RG int i=2;i<=num;i+=2) g[i].flow=g[i^1].flow=0;
     85     RG int flow=maxflow(id[L],id[R]); ++cnt,Dfs(id[L]);
     86     for (RG int i=1;i<=n;++i){
     87     if (vis[i]!=cnt) continue;
     88     for (RG int j=1;j<=n;++j)
     89         if (vis[j]!=cnt) ans[i][j]=ans[j][i]=min(ans[i][j],flow);
     90     }
     91     RG int l=L,r=R;
     92     for (RG int i=L;i<=R;++i) (vis[id[i]]==cnt)?tmp[l++]=id[i]:tmp[r--]=id[i];
     93     for (RG int i=L;i<=R;++i) id[i]=tmp[i];
     94     random_shuffle(id+L,id+l),random_shuffle(id+r+1,id+R+1);
     95     solve(L,l-1),solve(r+1,R); return;
     96 }
     97 
     98 il void work(){
     99     memset(ans,0x3f3f3f,sizeof(ans)),n=gi(),m=gi(),num=1;
    100     for (RG int i=1,u,v,w;i<=m;++i)
    101     u=gi(),v=gi(),w=gi(),insert(u,v,w),insert(v,u,w);
    102     for (RG int i=1;i<=n;++i) id[i]=i;
    103     random_shuffle(id+1,id+n+1),solve(1,n);
    104     for (RG int i=1;i<n;++i)
    105     for (RG int j=i+1;j<=n;++j) st[++top]=ans[i][j];
    106     sort(st+1,st+top+1);
    107     for (RG int i=1;i<=top;++i) if (st[i]!=st[i-1]) ++Ans;
    108     printf("%d
    ",Ans); return;
    109 }
    110 
    111 int main(){
    112     File("cut");
    113     work();
    114     return 0;
    115 }
  • 相关阅读:
    做个坚强的逆行者,献给终日奋斗的你我——《当幸福来敲门》
    学习jvm,关于MAT an internal error occurred during:"Parsing heap dump" from问题
    很详尽KMP算法(厉害)
    插入排序[数据结构](复习)
    JVM监控工具介绍jstack, jconsole, jinfo, jmap, jdb, jstat(复制)
    Hadoop集群配置搭建
    Tomcat IO阻塞异常
    centos通过yum安装jdk
    关于PHPExcel上传Excel单元格富文本和时间类型读取数据问题
    负载均衡集群总结(Haproxy)
  • 原文地址:https://www.cnblogs.com/wfj2048/p/7156197.html
Copyright © 2020-2023  润新知