codeforces #304 E 546E E. Soldier and Traveling(最大流)
来源:互联网 发布:matlab 数据反转 编辑:程序博客网 时间:2024/05/17 22:53
题目链接:
点击打开链接
题目大意:
给出一个无向图,每个点有一个值,只能给它周围的一个点一些值,然后达到目标的点权
题目分析:
考虑到点之间的值相互交换,想到了网络流,那么对于每个点,先要拆点,一个点代表起始状态,另一个代表目标状态,也就是同一个点拆成的两个点一定是可以链接,而且权值就是a[i],然后对于每条边,将起始点和目标点连接,因为目标点的流量由起始点的流量和与它相连的其他起始点的流量决定,所以可以利用最大流做,如果最后得到的最大流等于目标点的总数,那么就能完成题目要求,否则不能,然后源点要连向起始点提供流量,目标点连向汇点,容量为目标的点权值,那么走的流量记录在起始点和目标点之间,利用汇点判断能否成功,然后利用边的流量来记录,然后直接输出即可
代码如下:
拆完点之后,套模板.........
#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>#include <queue>#define N 207#define INF 0x3f3f3f3f#define MAX 10000using namespace std;int n,m,u,v;int sum1,sum2;int a[N];int b[N];int s[N][N];int d[N];bool bfs ( ){ queue<int> q; memset ( d , -1 , sizeof ( d ) ); d[0] = 0; q.push (0); while ( !q.empty() ) { int v = q.front(); q.pop(); for ( int i = 0 ; i <= 2*n+1 ; i++ ) if ( d[i] == -1 && s[v][i] ) { d[i] = d[v]+1; q.push ( i ); } } return d[2*n+1] != -1;}int dfs ( int v , int cur_flow ){ //cout << v << endl; int dt = cur_flow; if ( v == 2*n+1 ) return cur_flow; for ( int i = 0 ; i <= 2*n+1 ; i++ ) { if ( s[v][i] > 0 && d[v]+1 == d[i] ) { int flow = dfs ( i , min ( dt , s[v][i] ) ); s[v][i] -= flow; s[i][v] += flow; dt -= flow; } } return cur_flow - dt;}void dinic ( ){ int cur_flow , ans = 0; //int cnt = 1000000; while ( bfs() ) { while ( cur_flow = dfs ( 0 , INF ) ) ans += cur_flow; } //cout << "OKAY!" << endl; if ( ans != sum1 ) { puts("NO"); return; } puts("YES"); for ( int i = 1 ; i <= n ; i++ ) { for ( int j = n+1 ; j <= 2*n ; j++ ) if ( !s[i][j] ) printf ( "0 " ); else printf ( "%d " , INF - s[i][j] ); puts(""); }}int main ( ){ while ( ~scanf ( "%d%d" , &n , &m )) { sum1 = 0 , sum2 = 0; memset ( s , 0 , sizeof ( s ) ); for ( int i = 1 ; i <= n ; i++ ) { scanf ( "%d" , &a[i] ); sum1 += a[i]; s[0][i] = a[i]; s[i][n+i] = INF; } for ( int i = 1 ; i <= n ; i++ ) { scanf ( "%d" , &b[i] ); sum2 += b[i]; s[n+i][2*n+1] = b[i]; } while ( m-- ) { int u,v; scanf ( "%d%d" , &u , &v ); s[u][v+n] = INF; s[v][u+n] = INF; } if ( sum1 != sum2 ) { puts("NO"); continue; } dinic(); }}
0 0
- codeforces #304 E 546E E. Soldier and Traveling(最大流)
- Codeforces 546E - Soldier and Traveling (最大流)
- Codeforces 546E Soldier and Traveling (最大流)
- Codeforces 546E Soldier and Traveling 最大流 C#实现
- codeforces 546 E. Soldier and Traveling
- 【codeforces 546E】Soldier and Traveling
- codeforces 546e Soldier and Traveling
- Codeforces Round #304 (Div. 2) 546 E - Soldier and Traveling 最大流
- E. Soldier and Traveling (CF 304 div2) 最大流
- codeforces-546E. Soldier and Traveling(网络流)
- codeforces 546E. Soldier and Traveling 网络流
- CodeForces 546E - Soldier and Traveling(最大流+输出边流量)
- Codeforces 546 E Soldier and Traveling【最大流Dinic+判断残余网络】
- Codeforces 546E Soldier and Traveling (最大流+输出流量分配方案)
- Codeforces Round #304 (Div. 2) E - Soldier and Traveling 最大流 isap
- Codeforces Round #304 (Div. 2) E. Soldier and Traveling 最大流 Dinic EK 算法
- Codeforces Round #304 (Div. 2) E. Soldier and Traveling 复习一下最大流算法
- Codeforces Round #304 (Div. 2) E. Soldier and Traveling
- android-Eclipse,32位的工程导入64位Eclipse里,中文乱码
- limit - Mysql
- NYOJ 125 盗梦空间
- 机器学习中的bagging技巧
- java基础知识笔记
- codeforces #304 E 546E E. Soldier and Traveling(最大流)
- .net4.5使用async和await异步编程实例
- OSPF中的 DR的选举规则
- 反攻
- collectionView添加头部view
- OpenCV配置 Win7 Win8 VS2010 VS2012
- 黑马程序员——流程控制和函数详解
- storm官方文档
- java内功之jvm加载双亲模式