4519: [Cqoi2016]不同的最小割
2016-09-28 13:17
357 查看
4519: [Cqoi2016]不同的最小割
Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 524 Solved: 325
[Submit][Status][Discuss]
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 41 2 3
1 3 6
2 4 5
3 4 4
Sample Output
3HINT
Source
[Submit][Status][Discuss]
构建一棵最小割树即可
传送门
Dinic打残了。。
#include<iostream> #include<cstdio> #include<queue> #include<vector> #include<bitset> #include<algorithm> #include<cstring> #include<map> #include<stack> #include<set> #include<cmath> #include<ext/pb_ds/priority_queue.hpp> using namespace std; const int maxn = 1E3 + 10; const int maxm = 1E5 + 10; const int INF = ~0U>>1; struct E{ int to,cap,flow; E(){} E(int to,int cap,int flow): to(to),cap(cap),flow(flow){} }edgs[maxm]; int n,m,s,t,cur[maxn],L[maxn],fa[maxn],va[maxn] ,cnt,Cnt,x[maxm],y[maxm],w[maxm],vis[maxn]; vector <int> v[maxn]; queue <int> Q; void Add(int x,int y,int cap) { v[x].push_back(cnt); edgs[cnt++] = E(y,cap,0); v[y].push_back(cnt); edgs[cnt++] = E(x,0,0); } bool BFS() { L[s] = 1; vis[s] = ++Cnt; Q.push(s); while (!Q.empty()) { int k = Q.front(); Q.pop(); for (int i = 0; i < v[k].size(); i++) { E e = edgs[v[k][i]]; if (e.cap == e.flow) continue; if (vis[e.to] == Cnt) continue; vis[e.to] = Cnt; L[e.to] = L[k] + 1; Q.push(e.to); } } return vis[t] == Cnt; } int Dicnic(int x,int a) { if (x == t) return a; int flow = 0; for (int &i = cur[x]; i < v[x].size(); i++) { E &e = edgs[v[x][i]]; if (e.cap == e.flow) continue; if (L[e.to] != L[x] + 1) continue; int f = Dicnic(e.to,min(a,e.cap - e.flow)); if (!f) continue; e.flow += f; edgs[v[x][i]^1].flow -= f; a -= f; flow += f; if (!a) return flow; } if (!flow) L[x] = -1; return flow; } int getint() { char ch = getchar(); int ret = 0; while (ch < '0' || '9' < ch) ch = getchar(); while ('0' <= ch && ch <= '9') ret = ret*10 + ch - '0',ch = getchar(); return ret; } int main() { #ifdef DMC freopen("DMC.txt","r",stdin); #endif n = getint(); m = getint(); for (int i = 1; i <= m; i++) { int x = getint(); int y = getint(); int w = getint(); Add(x,y,w); Add(y,x,w); } for (int i = 2; i <= n; i++) fa[i] = 1; for (int i = 2; i <= n; i++) { s = i; t = fa[i]; int MaxFlow = 0; while (BFS()) { for (int i = 1; i <= n; i++) cur[i] = 0; MaxFlow += Dicnic(s,INF); } va[i] = MaxFlow; for (int j = i + 1; j <= n; j++) if (fa[j] == fa[i] && vis[j] == Cnt) fa[j] = i; for (int i = 0; i < cnt; i++) edgs[i].flow = 0; } sort(va + 2,va + n + 1); int Ans = 0; va[1] = -INF; for (int i = 2; i <= n; i++) if (va[i] != va[i-1]) ++Ans; cout << Ans; return 0; }
相关文章推荐
- HDU1049
- 微信小程序,大多数人都搞错的八个问题
- 【BZOJ1006】【HNOI2008】神奇的国度
- 笔记本中美化代码的方法
- 设计模式-单例模式
- atof函数详解
- 电子工程师必会的十大电子元器件
- 蓝鸥零基础学习HTML5第九讲 兼容性六
- 6.Laravel自定义类引入和命名空间问题
- 你的灯亮着吗?
- WKWebView针对于Cordova的IOS平台性能提升
- view可以跟随滑动,且滑过一定高度固定在头部
- 从虚短虚断分析基本的运算放大电路
- Lamport面包店算法
- 微信小程序把玩(三十四)Audio API
- java 使用正则表达式过滤HTML中标签
- Android混淆的深度理解
- iOS开发UI篇—CAlayer(创建图层)
- 2016第40周三
- 网络-----VLAN