博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【BZOJ4519】[Cqoi2016]不同的最小割 最小割树
阅读量:5247 次
发布时间:2019-06-14

本文共 2408 字,大约阅读时间需要 8 分钟。

【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

题解:同

 

#include 
#include
#include
#include
#include
using namespace std;int n,m,cnt,S,T,ans;int to[20000],next[20000],val[20000],head[1000],d[1000];int map[1000][1000],p[1000],pp[1000],s[1000000];queue
q;void add(int a,int b,int c){ to[cnt]=b,val[cnt]=c,next[cnt]=head[a],head[a]=cnt++; to[cnt]=a,val[cnt]=c,next[cnt]=head[b],head[b]=cnt++;}int dfs(int x,int mf){ if(x==T) return mf; int k,temp=mf,i; for(i=head[x];i!=-1;i=next[i]) { if(d[to[i]]==d[x]+1&&val[i]) { k=dfs(to[i],min(temp,val[i])); if(!k) d[to[i]]=0; val[i]-=k,val[i^1]+=k,temp-=k; if(!temp) break; } } return mf-temp;}int bfs(){ while(!q.empty()) q.pop(); memset(d,0,sizeof(d)); d[S]=1,q.push(S); int i,u; while(!q.empty()) { u=q.front(),q.pop(); for(i=head[u];i!=-1;i=next[i]) { if(!d[to[i]]&&val[i]) { d[to[i]]=d[u]+1; if(to[i]==T) return 1; q.push(to[i]); } } } return 0;}void solve(int l,int r){ if(l==r) return ; S=p[l],T=p[r]; int i,j,h1=l,h2=r,mf=0; for(i=0;i
>1; while(bfs()) mf+=dfs(S,1<<30); for(i=1;i<=n;i++) if(d[i]) for(j=1;j<=n;j++) if(!d[j]) map[i][j]=map[j][i]=min(map[i][j],mf); for(i=l;i<=r;i++) { if(d[p[i]]) pp[h1++]=p[i]; else pp[h2--]=p[i]; } for(i=l;i<=r;i++) p[i]=pp[i]; solve(l,h2),solve(h1,r);}int rd(){ int ret=0,f=1; char gc=getchar(); while(gc<'0'||gc>'9') {if(gc=='-')f=-f; gc=getchar();} while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar(); return ret*f;}int main(){ n=rd(),m=rd(); int i,j,a,b,c,pre; memset(head,-1,sizeof(head)); memset(map,0x3f,sizeof(map)); for(i=1;i<=m;i++) a=rd(),b=rd(),c=rd(),add(a,b,c); for(i=1;i<=n;i++) p[i]=i; solve(1,n); for(i=1;i<=n;i++) for(j=i+1;j<=n;j++) s[++s[0]]=map[i][j]; sort(s+1,s+s[0]+1); for(pre=-1,i=1;i<=s[0];i++) if(s[i]>pre) pre=s[i],ans++; printf("%d",ans); return 0;}

转载于:https://www.cnblogs.com/CQzhangyu/p/7095155.html

你可能感兴趣的文章
vue route 跳转
查看>>
【雷电】源代码分析(二)-- 进入游戏攻击
查看>>
Entityframework:“System.Data.Entity.Internal.AppConfig”的类型初始值设定项引发异常。...
查看>>
Linux中防火墙centos
查看>>
mysql新建用户,用户授权,删除用户,修改密码
查看>>
FancyCoverFlow
查看>>
JS博客
查看>>
如何设置映射网络驱动器的具体步骤和方法
查看>>
ASP.NET WebApi 基于OAuth2.0实现Token签名认证
查看>>
283. Move Zeroes把零放在最后面
查看>>
Visual Studio Code 打开.py代码报Linter pylint is not installed解决办法
查看>>
Python 数据类型
查看>>
S5PV210根文件系统的制作(一)
查看>>
51NOD 1244 莫比乌斯函数之和
查看>>
centos下同时启动多个tomcat
查看>>
slab分配器
查看>>
数据清洗
查看>>
【读书笔记】C#高级编程 第三章 对象和类型
查看>>
Struts2工作原理
查看>>
针对sl的ICSharpCode.SharpZipLib,只保留zip,gzip的流压缩、解压缩功能
查看>>