POJ 2112 Optimal Milking 二分+floyd+最大流
dinic
1719MS
View Code
#include<stdio.h> #include<string.h> #include<algorithm> #include<queue> using namespace std; #define INF 1000000 #define maxn 250 int dis[maxn][maxn]; int c[maxn][maxn]; bool vis[maxn]; bool sign[maxn][maxn]; int K,C,M; int s, t, n; void floyd() { int i, j, k; for(k=1;k<=n;k++) for(i=1;i<=n;i++) for(j=1;j<=n;j++) if(k!=i&&k!=j) if(dis[i][j] > dis[i][k] + dis[k][j]) dis[i][j] = dis[i][k] + dis[k][j]; } void build(int tmp) { int i, j; memset(c,0,sizeof(c)); for(i=K+1;i<=n;i++)c[0][i]=1; for(i=1;i<=K;i++)c[i][n+1]=M; for(i=K+1;i<=n;i++) for(j=1;j<=K;j++) if(dis[i][j] <= tmp)c[i][j]=1; } bool bfs() { int i; memset(vis,false,sizeof(vis)); memset(sign,false,sizeof(sign)); queue<int>q; q.push(s); vis[s]=true; while(!q.empty()) { int v = q.front();q.pop(); for(i=0;i<=t;i++) { if(!vis[i]&&c[v][i]) { vis[i]=true; q.push(i); sign[v][i]=true; } } } if(!vis[t])return false; return true; } int dfs(int v, int sum) { if(v == t)return sum; int flow =0; int i; for(i=0;i<=t;i++) if(sign[v][i]) { int aug = dfs(i,min(sum,c[v][i])); c[v][i] -= aug; c[i][v] += aug; flow +=aug; if(flow == sum)return flow; } return flow; } int main() { int i, j; scanf("%d%d%d",&K,&C,&M); n = K+C;s=0;t=n+1; for(i=1;i<=n;i++) for(j=1;j<=n;j++) { scanf("%d",&dis[i][j]); if(!dis[i][j])dis[i][j]=INF; } floyd(); int l =0,r =10000,mid; while(l < r) { int ans = 0; mid = (l + r)>> 1; build(mid); while(bfs())ans += dfs(0,INF); if(ans >=C)r = mid; else l= mid+1; } printf("%d\n",r); return 0; }
sap
172MS
View Code
#include<stdio.h> #include<string.h> #include<algorithm> #include<queue> using namespace std; #define INF 1000000 #define maxn 250 int dis[maxn][maxn]; int c[maxn][maxn]; bool vis[maxn]; int d[maxn]; int K,C,M; int s, t, n; void floyd() { int i, j, k; for(k=1;k<=n;k++) for(i=1;i<=n;i++) for(j=1;j<=n;j++) if(k!=i&&k!=j) if(dis[i][j] > dis[i][k] + dis[k][j]) dis[i][j] = dis[i][k] + dis[k][j]; } void build(int tmp) { int i, j; memset(c,0,sizeof(c)); for(i=K+1;i<=n;i++)c[0][i]=1; for(i=1;i<=K;i++)c[i][n+1]=M; for(i=K+1;i<=n;i++) for(j=1;j<=K;j++) if(dis[i][j] <= tmp)c[i][j]=1; } bool bfs() { int i; memset(vis,false,sizeof(vis)); memset(d,0,sizeof(d)); queue<int>q; q.push(t); vis[t]=true; while(!q.empty()) { int v = q.front();q.pop(); for(i=0;i<=t;i++) { if(!vis[i]&&c[i][v]) { vis[i]=true; q.push(i); d[i]=d[v]+1; } } } if(!vis[s]||d[s]>=t+1)return false; return true; } int dfs(int v, int sum) { if(v == t)return sum; int flow =0; int i; for(i=0;i<=t;i++) if(c[v][i]&&d[v]==d[i]+1) { int aug = dfs(i,min(sum,c[v][i])); c[v][i] -= aug; c[i][v] += aug; flow +=aug; if(flow == sum)return flow; } return flow; } int main() { int i, j; scanf("%d%d%d",&K,&C,&M); n = K+C;s=0;t=n+1; for(i=1;i<=n;i++) for(j=1;j<=n;j++) { scanf("%d",&dis[i][j]); if(!dis[i][j])dis[i][j]=INF; } floyd(); int l =0,r =10000,mid; while(l < r) { int ans = 0; mid = (l + r)>> 1; build(mid); while(bfs())ans += dfs(0,INF); if(ans >=C)r = mid; else l= mid+1; } printf("%d\n",r); return 0; }
sap+gap优化
View Code
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #define maxn 235 #define maxm 6003 #define inf 1000000000 int min(int a, int b) { return a < b ? a : b; } struct E { int v, next, c; }edge[maxm << 2]; int head[maxn], tot; int n, m, k, c; void add(int s, int t, int c) { edge[tot].v = t; edge[tot].c = c; edge[tot].next = head[s]; head[s] = tot++; edge[tot].v = s; edge[tot].c = 0; edge[tot].next = head[t]; head[t] = tot++; } void init() { tot = 0; memset(head, -1, sizeof(head)); } int gap[maxn], dis[maxn], pre[maxn], cur[maxn]; int sap(int s, int t, int vs) { memset(gap, 0, sizeof(gap)); memset(dis, 0, sizeof(dis)); gap[0] = vs; memcpy(cur, head, sizeof(head)); int i, u = pre[s] = s, maxf = 0, aug = inf, v; while(dis[s] < vs) { loop: for(i = head[u]; i != -1; i = edge[i].next) { v = edge[i].v; if(edge[i].c > 0 && dis[u] == dis[v] + 1) { aug = min(aug, edge[i].c); pre[v] = u; cur[u] = i; u = v; if(u == t) { for(u = pre[u]; v != s; v = u, u = pre[u]) { edge[cur[u]].c -= aug; edge[cur[u]^1].c += aug; } maxf += aug; aug = inf; } goto loop; } } int min_d = vs; for(i = head[u]; i != -1; i = edge[i].next) { v = edge[i].v; if(edge[i].c > 0 && dis[v] < min_d) min_d = dis[v]; } if( !(--gap[dis[u]])) break; ++gap[dis[u] = min_d + 1]; u = pre[u]; } return maxf; } int map[maxn][maxn]; void floyd() { int i, j, x; for(x = 1; x <= k+c; x++) for(i = 1; i <= k+c; i++) for(j = 1; j <= k+c; j++) if(x != i && x != j && i != j) map[i][j] = min(map[i][j], map[i][x] + map[x][j]); } int S, T; void build(int mid) { init(); int i, j; for(i = 1; i <= k; i++) add(i, T, m); for(i = k+1; i <= k+c; i++) add(S, i, 1); for(i = k+1; i <= k+c; i++) for(j = 1; j <= k; j++) if(map[i][j] <= mid) add(i, j, 1); } int main() { int i, j; while( ~scanf("%d%d%d", &k, &c, &m)) { for(i = 1; i <= k+c; i++) for(j = 1; j <= k+c; j++) { scanf("%d", &map[i][j]); if(!map[i][j]) map[i][j] = inf; } floyd(); S = 0; T = k+c+1; int l = 0, r = inf; while(l <= r) { int mid = (l + r) >> 1; build(mid); if( sap(S, T, k+c+2) >= c) r = mid - 1; else l = mid + 1; } printf("%d\n", l); } return 0; }


浙公网安备 33010602011771号