[bzoj2521][Shoi2010]最小生成树 最小割
来源:互联网 发布:sql select语句例子 编辑:程序博客网 时间:2024/05/29 02:30
2521: [Shoi2010]最小生成树
Time Limit: 10 Sec Memory Limit: 128 MB[Submit][Status][Discuss]
Description
Secsa最近对最小生成树问题特别感兴趣。他已经知道如果要去求出一个n个点、m条边的无向图的最小生成树有一个Krustal算法和另一个Prim的算法。另外,他还知道,某一个图可能有多种不同的最小生成树。例如,下面图 3中所示的都是图 2中的无向图的最小生成树:
当然啦,这些都不是今天需要你解决的问题。Secsa想知道对于某一条无向图中的边AB,至少需要多少代价可以保证AB边在这个无向图的最小生成树中。为了使得AB边一定在最小生成树中,你可以对这个无向图进行操作,一次单独的操作是指:先选择一条图中的边 P1P2,再把图中除了这条边以外的边,每一条的权值都减少1。如图 4所示就是一次这样的操作:
Input
输入文件的第一行有3个正整数n、m、Lab分别表示无向图中的点数、边数、必须要在最小生成树中出现的AB边的标号。
接下来m行依次描述标号为1,2,3…m的无向边,每行描述一条边。每个描述包含3个整数x、y、d,表示这条边连接着标号为x、y的点,且这条边的权值为d。
输入文件保证1<=x,y<=N,x不等于y,且输入数据保证这个无向图一定是一个连通图。
Output
输出文件只有一行,这行只有一个整数,即,使得标号为Lab边一定出现最小生成树中的最少操作次数。
Sample Input
4 6 1
1 2 2
1 3 2
1 4 3
2 3 2
2 4 4
3 4 5
1 2 2
1 3 2
1 4 3
2 3 2
2 4 4
3 4 5
Sample Output
1
HINT
第1个样例就是问题描述中的例子。
1<=n<=500,1<=M<=800,1<=D<10^6
Source
S:u[id]
T:v[id]
u[i]->v[i]:w[id]-w[i]+1
需要解释吗
好吧
其它边-1相当于这条加一(这只对题目理解有帮助)
如果id这条边在最小生成树上
那么比他小的边加入后u[id]与v[id]不联通
如果联通,就去割掉某些边使其不联通
代价为边权差+1
#include<iostream>#include<cstring>#include<cstdio>#define INF 0x7fffffffusing namespace std;const int N = 30005;int ans=0, tot=0;int n, m, S, T, cnt = 1, id;int q[N], last[N], h[N], cur[N], u[N], v[N], w[N];struct Edge{int to,next,v;}e[1000005];void insert( int u, int v, int w ){e[++cnt].to = v; e[cnt].v = w; e[cnt].next = last[u]; last[u] = cnt;e[++cnt].to = u; e[cnt].v = 0; e[cnt].next = last[v]; last[v] = cnt;}bool bfs(){ int head = 0, tail = 1; memset(h,-1,sizeof(h)); q[0] = S; h[S] = 0; while( head != tail ){ int u = q[head++]; for( int i = last[u]; i; i = e[i].next ){ int v = e[i].to; if( h[v] == -1 && e[i].v ) { q[tail++] = v; h[v] = h[u] + 1; } } } return h[T] != -1;}int dfs( int x, int f ){ if( x == T ) return f; int w,used=0; for( int i = cur[x]; i; i = e[i].next ){ int v = e[i].to; if( h[v] == h[x] + 1 ){ w = dfs( v, min( f-used, e[i].v ) ); used += w; e[i].v -= w; e[i^1].v += w; if( e[i].v ) cur[x] = i; if( used == f ) return f; } } if( !used ) h[x] = -1; return used;}void dinic(){ while( bfs() ){ for( int i = 0; i <= n+1; i++ ) cur[i] = last[i]; ans += dfs( S, INF ); }}int main(){scanf("%d%d%d", &n, &m, &id);for( int i = 1; i <= m; i++ ) scanf("%d%d%d", &u[i], &v[i], &w[i]);S = u[id]; T= v[id];for( int i = 1; i <= m; i++ )if( w[i] <= w[id] && i^id ){insert( u[i], v[i], w[id]-w[i]+1 );insert( v[i], u[i], w[id]-w[i]+1 );}dinic();printf("%d\n", ans);return 0;}
阅读全文
0 0
- bzoj2521: [Shoi2010]最小生成树 最小割
- 【bzoj2521】【SHOI2010】【最小生成树】【最小割】
- [bzoj2521][Shoi2010]最小生成树 最小割
- [BZOJ2521][Shoi2010]最小生成树(最小割)
- [BZOJ2521][Shoi2010]最小生成树(最小割)
- 【最小割Dinic】BZOJ2521(Shoi2010)[最小生成树]题解
- 【贪心+最小割】BZOJ2521 [Shoi2010]最小生成树
- BZOJ2521: [Shoi2010]最小生成树
- bzoj 2521: [Shoi2010]最小生成树(最小割)
- BZOJ 2521: [Shoi2010]最小生成树&&2229: [Zjoi2011]最小割
- 2521: [Shoi2010]最小生成树
- 【bzoj 2521】 [Shoi2010] 最小生成树(网络流最小割)
- 【bzoj 2521】: [Shoi2010]最小生成树
- 【BZOJ】2521 [Shoi2010]最小生成树 网络流
- BZOJ 2561 最小生成树 最小割
- 【最小割】bzoj2561 最小生成树
- bzoj2561 最小生成树 最小割
- BZOJ 2561 - 最小生成树 + 最小割
- 指针运算
- 数据库sql如何查询某个字段只含有数字和字母或者是汉字
- 设计模式6-代理模式
- javaseday12(线程,同步代码块 函数,线程安全,死锁)
- [SMOJ2072]长路
- [bzoj2521][Shoi2010]最小生成树 最小割
- mongodb 杂记
- 数据结构和算法部分
- 设计模式
- 微信小程序开发步骤讲解和实用小技巧
- MySQL查看表占用空间大小(转)
- 微信Redirect_uri参数错误解决方法
- GridView实现加载本地所有图片
- HTTP Status 500