UVA 1515 (最小割)
来源:互联网 发布:更新mac系统版本出错 编辑:程序博客网 时间:2024/05/22 03:23
额...感觉关键还是要看出是最小割,然后用割的思想去考虑怎么建图...
然后慢一点的最大流方法会被卡掉
#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <vector>#include <queue>using namespace std;const int INF = 1e8;#define maxn 3333#define maxm 411111int n, m;int s, t;int dd, ff, bb;struct Edge{ int from, to,next,cap,flow; void get(int u,int a,int b,int c,int d) { from = u; to = a; next = b; cap = c; flow = d; }}edge[maxm];int tol;int head[maxn];int gap[maxn],dep[maxn],pre[maxn],cur[maxn];void init(){ tol=0; memset(head,-1,sizeof(head));}void add_edge(int u,int v,int w,int rw=0){ edge[tol].get(u, v,head[u],w,0);head[u]=tol++; edge[tol].get(v, u,head[v],rw,0);head[v]=tol++;}int sap(int start,int end,int N){ memset(gap,0,sizeof(gap)); memset(dep,0,sizeof(dep)); memcpy(cur,head,sizeof(head)); int u=start; pre[u]=-1; gap[0]=N; int ans=0; while(dep[start]<N) { if(u==end) { int Min=INF; for(int i=pre[u];i!=-1;i=pre[edge[i^1].to]) if(Min>edge[i].cap-edge[i].flow) Min=edge[i].cap-edge[i].flow; for(int i=pre[u];i!=-1;i=pre[edge[i^1].to]) { edge[i].flow+=Min; edge[i^1].flow-=Min; } u = start; ans+=Min; continue; } bool flag=false; int v; for(int i=cur[u];i !=-1;i=edge[i].next) { v=edge[i].to; if(edge[i].cap-edge[i].flow&&dep[v]+1==dep[u]) { flag=true; cur[u]=pre[v]=i; break; } } if(flag) { u=v; continue; } int Min=N; for(int i=head[u];i!=-1;i=edge[i].next) if(edge[i].cap-edge[i].flow&&dep[edge[i].to]<Min) { Min=dep[edge[i].to]; cur[u]=i; } gap[dep[u]]--; if(!gap[dep[u]]) return ans; dep[u]=Min+1; gap[dep[u]]++; if(u!=start) u=edge[pre[u]^1].to; } return ans;}char mp[55][55];#define move Moveconst int move[2][2] = {{0, 1}, {1, 0}};bool legal (int x, int y) { if (x < 0 || x >= n || y < 0 || y >= m) return 0; return 1;}int main () { //freopen ("in.txt", "r", stdin); int tt; scanf ("%d", &tt); while (tt--) { init (); scanf ("%d%d", &m, &n); scanf ("%d%d%d", &dd, &ff, &bb); for (int i = 0; i < n; i++) { scanf ("%s", mp[i]); } int add = 0; for (int i = 0; i < m; i++) { if (mp[0][i] == '.') { add += ff; mp[0][i] = '#'; } if (mp[n-1][i] == '.') { add += ff; mp[n-1][i] = '#'; } } for (int i = 0; i < n; i++) { if (mp[i][0] == '.') { add += ff; mp[i][0] = '#'; } if (mp[i][m-1] == '.') { add += ff; mp[i][m-1] = '#'; } } int N = n*m+2, s = n*m, t = n*m+1; for (int i = 0; i < n; i++) {//两点之间连边 for (int j = 0; j < m; j++) { for (int k = 0; k < 2; k++) { int xx = i+move[k][0], yy = j+move[k][1]; if (!legal (xx, yy)) continue; add_edge (i*m+j, xx*m+yy, bb); add_edge (xx*m+yy, i*m+j, bb); } } } //cout << ".." << endl; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { if (i == 0 || i == n-1 || j == 0 || j == m-1) { //cout << i << "\\\\" << j << endl; add_edge (s, i*m+j, INF); } else { if (mp[i][j] == '.') { add_edge (i*m+j, t, ff); } else add_edge (s, i*m+j, dd); } } } //cout << add << endl; int ans = sap (s, t, N); printf ("%d\n", ans+add); } return 0;}
0 0
- UVA 1515 (最小割)
- UVa 1515 简单最小割模型
- 最小割 UVA 1515 Pool construction
- UVA 1515 Pool construction [最小割]
- UVA 1515 Pool construction(最小割)
- uva 1515 Pool construction(最小割)
- uva 11248 最小割
- 最大流最小割 UVA
- 最大流,最小割(水塘,uva 1515)
- UVA 1212 - Duopoly(最小割)
- UVA 11248 网络扩容 最小割
- 【最小割】 UVA 11248 Frequency Hopping
- UVA 11248 Frequency Hopping 最小割
- UVA 10480 Sabotage (最大流最小割)
- UVA 1212 - Duopoly(最小割)
- UVa 10480 Sabotage ( 最小割最大流定理)
- UVa 11248 - Frequency Hopping - 最大流 - 最小割
- UVA 11248 Frequency Hopping(最大流、最小割)
- iOS基本动画
- 海潮负荷模型ES2012
- android学习——activity生命周期和切换逻辑
- java中变量的几种名称fileds,parameters,arguments
- jquery实现全选和反选
- UVA 1515 (最小割)
- 299. Bulls and Cows
- HDOJ 3788 ZOJ问题
- Leetcode:228. Summary Ranges(JAVA)
- 学生管理新系统(C++版)
- Apache kafka工作原理
- B-树和B+树的应用:数据搜索和数据库索引
- WM_DEVICECHANGE 检测USB的热拔插事件
- 列出连通集-----简单dfs+bfs