-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
52f579b
commit 1744a0a
Showing
8 changed files
with
816 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
/* Bismillahir Rahmanir Rahim */ | ||
|
||
#include <bits/stdc++.h> | ||
|
||
#define rep(i, n) for(int i=0;i<n;i++) | ||
#define repn(i, n) for(int i=1;i<=n;i++) | ||
#define set(i, n) memset(i, n, sizeof(i)) | ||
|
||
#define mx 1007 | ||
#define pb push_back | ||
#define oo 1e9 | ||
|
||
#define f first | ||
#define s second | ||
|
||
using namespace std; | ||
|
||
typedef long long LL; | ||
typedef pair<int, int> pii; | ||
|
||
struct Edge { | ||
int u, v; | ||
LL cap, flow; | ||
Edge() {} | ||
Edge(int u, int v, LL cap): u(u), v(v), cap(cap), flow(0) {} | ||
}; | ||
|
||
struct Dinic { | ||
int N; | ||
vector<Edge> E; | ||
vector<vector<int>> g; | ||
vector<int> d, pt; | ||
|
||
Dinic(int N): N(N), E(0), g(N), d(N), pt(N) {} | ||
|
||
void AddEdge(int u, int v, LL cap) { | ||
if (u != v) { | ||
E.emplace_back(Edge(u, v, cap)); | ||
g[u].emplace_back(E.size() - 1); | ||
E.emplace_back(Edge(v, u, 0)); | ||
g[v].emplace_back(E.size() - 1); | ||
} | ||
} | ||
|
||
bool BFS(int S, int T) { | ||
queue<int> q({S}); | ||
fill(d.begin(), d.end(), N + 1); | ||
d[S] = 0; | ||
while(!q.empty()) { | ||
int u = q.front(); q.pop(); | ||
if (u == T) break; | ||
for (int k: g[u]) { | ||
Edge &e = E[k]; | ||
if (e.flow < e.cap && d[e.v] > d[e.u] + 1) { | ||
d[e.v] = d[e.u] + 1; | ||
q.emplace(e.v); | ||
} | ||
} | ||
} | ||
return d[T] != N + 1; | ||
} | ||
|
||
LL DFS(int u, int T, LL flow = -1) { | ||
if (u == T || flow == 0) return flow; | ||
for (int &i = pt[u]; i < g[u].size(); ++i) { | ||
Edge &e = E[g[u][i]]; | ||
Edge &oe = E[g[u][i]^1]; | ||
if (d[e.v] == d[e.u] + 1) { | ||
LL amt = e.cap - e.flow; | ||
if (flow != -1 && amt > flow) amt = flow; | ||
if (LL pushed = DFS(e.v, T, amt)) { | ||
e.flow += pushed; | ||
oe.flow -= pushed; | ||
return pushed; | ||
} | ||
} | ||
} | ||
return 0; | ||
} | ||
|
||
LL MaxFlow(int S, int T) { | ||
LL total = 0; | ||
while (BFS(S, T)) { | ||
fill(pt.begin(), pt.end(), 0); | ||
while (LL flow = DFS(S, T)) | ||
total += flow; | ||
} | ||
return total; | ||
} | ||
}; | ||
|
||
int n, m; | ||
string grid[mx]; | ||
int fx[] = {0, 0, +1, -1}; | ||
int fy[] = {+1, -1, 0, 0}; | ||
|
||
int in(int x, int y){ | ||
return m * x + y; | ||
} | ||
|
||
int out(int x, int y){ | ||
return m * x + y + n * m; | ||
} | ||
|
||
bool valid(int x, int y){ | ||
if(x < 0 || y < 0 || x >= n || y >= m) return false; | ||
return true; | ||
} | ||
|
||
int main(){ | ||
ios::sync_with_stdio(false); | ||
cin >> n >> m; | ||
rep(i, n) cin >> grid[i]; | ||
Dinic flow(n*m*2 + 3); | ||
rep(i, n){ | ||
rep(j, m){ | ||
if(grid[i][j] == 'X') flow.AddEdge(in(i, j), out(i, j), oo); | ||
else flow.AddEdge(in(i, j), out(i, j), 1); | ||
} | ||
} | ||
rep(i, n){ | ||
rep(j, m){ | ||
rep(f, 4){ | ||
int x = i + fx[f], y = j + fy[f]; | ||
if(valid(x, y)) flow.AddEdge(out(i, j), in(x, y), oo); | ||
} | ||
} | ||
} | ||
int source = n * m * 2 + 1, sink = source + 1; | ||
rep(i, m){ | ||
flow.AddEdge(source, in(0, i), oo); | ||
flow.AddEdge(source, in(n-1, i), oo); | ||
} | ||
for(int i=2;i<n-1;i++){ | ||
flow.AddEdge(source, in(i, 0), oo); | ||
flow.AddEdge(source, in(i, m-1), oo); | ||
} | ||
rep(i, n){ | ||
rep(j, m){ | ||
if(grid[i][j] == 'X'){ | ||
flow.AddEdge(out(i, j), sink, oo); | ||
if(i==0||i==n-1||j==0||j==m-1){ | ||
printf("-1\n"); | ||
return 0; | ||
} | ||
} | ||
} | ||
} | ||
cout << flow.MaxFlow(source, sink) << endl; | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
/* Bismiintahir Rahmanir Rahim */ | ||
|
||
#include <bits/stdc++.h> | ||
|
||
#define REP(i, n) for(int i=0;i<n;i++) | ||
#define repn(i, n) for(int i=1;i<=n;i++) | ||
#define set(i, n) memset(i, n, sizeof(i)) | ||
|
||
#define MAXN 50007 | ||
|
||
using namespace std; | ||
|
||
int N, M, matched[2 * MAXN], dist[2 * MAXN], pt[MAXN]; | ||
vector<int> g[MAXN]; | ||
|
||
bool bfs() { | ||
fill(dist, dist + 2 * N, -1); | ||
queue<int> q; | ||
REP (i, MAXN) if (!matched[i]) { | ||
dist[i] = 0; | ||
q.push(i); | ||
} | ||
bool found = false; | ||
while (!q.empty()) { | ||
int u = q.front(); q.pop(); | ||
if (u > N && !matched[u]) found = true; | ||
if (u <= N) { // left side | ||
for (auto v : g[u]) | ||
if (dist[v] == -1) { | ||
dist[v] = dist[u] + 1; | ||
q.push(v); | ||
} | ||
} else if (u > N && matched[u]) { // right side | ||
if (dist[matched[u]] == -1) { | ||
dist[matched[u]] = dist[u] + 1; | ||
q.push(matched[u]); | ||
} | ||
} | ||
} | ||
return found; | ||
} | ||
|
||
bool dfs(int u) { | ||
for (int &i = pt[u]; i < g[u].size(); ++i) { | ||
int v = g[u][i]; | ||
if (dist[v] == dist[u] + 1) { | ||
if (!matched[v] || (dist[matched[v]] == dist[v] + 1 && dfs(matched[v]))) { | ||
matched[v] = u; | ||
matched[u] = v; | ||
return true; | ||
} | ||
} | ||
} | ||
return false; | ||
} | ||
|
||
int hopcroft_karp() { | ||
int total = 0; | ||
while (bfs()) { | ||
fill(pt, pt + N, 0); | ||
REP (i, MAXN) | ||
if (!matched[i]) | ||
if (dfs(i)) ++total; | ||
} | ||
return total; | ||
} | ||
|
||
int main(){ | ||
int x, y; | ||
int m, e; | ||
scanf("%d %d %d", &N, &M, &e); | ||
while(e--){ | ||
scanf("%d %d", &x, &y); | ||
x--, y--; | ||
g[x].push_back(y); | ||
} | ||
printf("%d\n", hopcroft_karp()); | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
/* Bismillahir Rahmanir Rahim */ | ||
|
||
#include <bits/stdc++.h> | ||
|
||
#define rep(i, n) for(int i=0;i<n;i++) | ||
#define repn(i, n) for(int i=1;i<=n;i++) | ||
#define set(i, n) memset(i, n, sizeof(i)) | ||
|
||
#define mx 1000007 | ||
#define pb push_back | ||
#define inf (1 << 30) | ||
|
||
#define f first | ||
#define s second | ||
|
||
using namespace std; | ||
|
||
typedef long long ll; | ||
typedef pair<int, int> pii; | ||
|
||
typedef long long int64; | ||
|
||
const int | ||
MAXN = 502, | ||
MAXE = 100000, | ||
oo = (int)1e9; | ||
|
||
int T, V, L, E; | ||
int src, snk, sol; | ||
int cant[MAXN]; | ||
int best[MAXN]; | ||
int from[MAXN]; | ||
int head[MAXN]; | ||
struct edge { | ||
int u, v, w, cap, next; | ||
} edges[MAXE]; | ||
|
||
void add_edge( int u, int v, int w, int cap ) { | ||
edges[E++] = (edge){ u, v, +w, cap, head[u] }; | ||
head[u] = E - 1; | ||
edges[E++] = (edge){ v, u, -w, 0, head[v] }; | ||
head[v] = E - 1; | ||
} | ||
|
||
bool augment( int src, int snk ) { | ||
|
||
fill( best, best + V + 2, oo ); | ||
best[src] = 0; | ||
|
||
queue< int > Q; | ||
for ( Q.push( src ); !Q.empty(); Q.pop() ) { | ||
int u = Q.front(); | ||
for ( int e = head[u]; e != -1; e = edges[e].next ) { | ||
int v = edges[e].v; | ||
if ( edges[e].cap && best[u] + edges[e].w < best[v] ) { | ||
Q.push( v ); | ||
best[v] = best[u] + edges[e].w; | ||
from[v] = e; | ||
} | ||
} | ||
} | ||
|
||
if ( best[snk] == oo ) | ||
return false; | ||
|
||
sol += best[snk]; | ||
for ( int x = snk; x != src; x = edges[ from[x] ].u ) { | ||
edges[ from[x] ].cap--; | ||
edges[ from[x]^1 ].cap++; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
|
||
int main() { | ||
int x, y, c, m; | ||
int cas = 1; | ||
while(scanf("%d %d", &V, &m) == 2){ | ||
if(V == 0 && m == 0) break; | ||
memset( head, -1, sizeof( head ) ); | ||
memset( cant, 0, sizeof( cant ) ); | ||
src = 0; | ||
snk = V-1; | ||
E = 0; | ||
rep(i, m){ | ||
scanf("%d %d %d", &x, &y, &c); | ||
add_edge(x, y, c, 1); | ||
} | ||
sol = 0; | ||
bool flag = true; | ||
rep(i, 2){ | ||
if(augment(src, snk) == false){ | ||
flag = false; | ||
break; | ||
} | ||
} | ||
if(flag == false) printf("Instance #%d: Not possible\n", cas++); | ||
else printf("Instance #%d: %d\n", cas++, sol); | ||
} | ||
return 0; | ||
} | ||
|
Oops, something went wrong.