teamnote history merge
This commit is contained in:
17
2024fall/source/Graph/BipartiteMatching.cpp
Normal file
17
2024fall/source/Graph/BipartiteMatching.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
vector<int> sideadj[N];
|
||||
int selby[M];
|
||||
int chk[M], c;
|
||||
bool matching(int s)
|
||||
{
|
||||
for(auto i : sideadj[s])
|
||||
{
|
||||
if(chk[i] == c) continue;
|
||||
chk[i] = c;
|
||||
|
||||
if(selby[i] and !matching(selby[i])) continue;
|
||||
|
||||
selby[i] = s;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
85
2024fall/source/Graph/Dinic.cpp
Normal file
85
2024fall/source/Graph/Dinic.cpp
Normal file
@@ -0,0 +1,85 @@
|
||||
struct Edge
|
||||
{
|
||||
int to, cap, now;
|
||||
Edge* rev;
|
||||
Edge(int to,int cap):to(to), cap(cap), now(0){}
|
||||
int left(){return cap - now;}
|
||||
void flow(int f){now += f; rev->now -= f;}
|
||||
void reset(){now = 0;}
|
||||
};
|
||||
vector<Edge*> adj[N];
|
||||
|
||||
int lv[N]; bool chk[N];
|
||||
bool bfs(int S, int T)
|
||||
{
|
||||
queue<int> q;
|
||||
|
||||
q.push(S); lv[S] = 0; chk[S] = true;
|
||||
|
||||
while(!q.empty())
|
||||
{
|
||||
int s = q.front(); q.pop();
|
||||
for(auto i : adj[s])
|
||||
{
|
||||
if(i->left() and !chk[i->to])
|
||||
{
|
||||
lv[i->to] = lv[s]+1; chk[i->to] = true;
|
||||
q.push(i->to);
|
||||
}
|
||||
}
|
||||
}
|
||||
return chk[T];
|
||||
}
|
||||
|
||||
Edge* hist[N]; int last[N];
|
||||
bool dfs(int s, int T)
|
||||
{
|
||||
if(s == T) return true;
|
||||
|
||||
for(int &j=last[s]; j < adj[s].size(); j++)
|
||||
{
|
||||
int i = adj[s][j]->to;
|
||||
if(adj[s][j]->left() == 0 or lv[i] != lv[s]+1) continue;
|
||||
hist[i] = adj[s][j];
|
||||
|
||||
if(dfs(i, T)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
ll flow(int S,int T)
|
||||
{
|
||||
ll ans = 0;
|
||||
while(bfs(S, T))
|
||||
{
|
||||
while(dfs(S, T))
|
||||
{
|
||||
int m = 2e9;
|
||||
|
||||
int now = T;
|
||||
while(S != now)
|
||||
{
|
||||
m = min(m, hist[now]->left());
|
||||
now = hist[now]->rev->to;
|
||||
}
|
||||
now = T;
|
||||
while(S != now)
|
||||
hist[now]->flow(m), now = hist[now]->rev->to;
|
||||
ans += m;
|
||||
}
|
||||
|
||||
memset(last, 0, sizeof last);
|
||||
memset(chk, 0, sizeof chk);
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
// isDir : isDirected => 양방향 간선이면 false
|
||||
void connect(int from, int to, int cap, bool isDir = true)
|
||||
{
|
||||
Edge *fw, *bw;
|
||||
fw = new Edge(to, cap);
|
||||
bw = new Edge(from, !isDir ? cap : 0);
|
||||
fw->rev = bw; bw->rev = fw;
|
||||
adj[from].push_back(fw);
|
||||
adj[to].push_back(bw);
|
||||
}
|
||||
79
2024fall/source/Graph/MCMF.cpp
Normal file
79
2024fall/source/Graph/MCMF.cpp
Normal file
@@ -0,0 +1,79 @@
|
||||
struct Edge
|
||||
{
|
||||
int to, cap, now;
|
||||
ll cost;
|
||||
Edge* rev;
|
||||
Edge(int to,int cap, ll cost)
|
||||
:to(to), cap(cap), now(0), cost(cost){}
|
||||
int left(){return cap - now;}
|
||||
ll flow(int f)
|
||||
{now += f; rev->now -= f; return cost * f;}
|
||||
void reset(){now = 0;}
|
||||
};
|
||||
vector<Edge*> adj[N];
|
||||
Edge* hist[N]; ll dist[N]; bool inQueue[N], chk[N];
|
||||
bool spfa(int s, int t)
|
||||
{
|
||||
memset(dist, 0, sizeof(dist));
|
||||
memset(chk, 0, sizeof(chk)); chk[s] = true;
|
||||
|
||||
queue<int> q;
|
||||
memset(inQueue, 0, sizeof(inQueue));
|
||||
q.push(s); inQueue[s] = true;
|
||||
|
||||
while(!q.empty())
|
||||
{
|
||||
int now = q.front();
|
||||
q.pop(); inQueue[now] = false;
|
||||
|
||||
for(auto e : adj[now])
|
||||
{
|
||||
int next = e->to;
|
||||
if(e->left() > 0 and
|
||||
(chk[next] == false
|
||||
or dist[next] > dist[now] + e->cost))
|
||||
{
|
||||
chk[next] = true;
|
||||
dist[next] = dist[now] + e->cost;
|
||||
hist[next] = e;
|
||||
if(!inQueue[next])
|
||||
q.push(next), inQueue[next] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return chk[t];
|
||||
}
|
||||
// cost가 들어가면 항상 단방향만 가능하다. (양방향 : 2번 connect)
|
||||
void connect(int from, int to, int cap, ll cost)
|
||||
{
|
||||
Edge *fw, *bw;
|
||||
fw = new Edge(to, cap, cost);
|
||||
bw = new Edge(from, 0, -cost);
|
||||
fw->rev = bw; bw->rev = fw;
|
||||
adj[from].push_back(fw);
|
||||
adj[to].push_back(bw);
|
||||
}
|
||||
//maximum matching & minimum cost
|
||||
pair<ll, ll> flow(int S,int T)
|
||||
{
|
||||
ll ans = 0; ll cost = 0;
|
||||
while(spfa(S, T))
|
||||
{
|
||||
int m = 2e9;
|
||||
|
||||
int now = T;
|
||||
while(S != now)
|
||||
{
|
||||
m = min(m, hist[now]->left());
|
||||
now = hist[now]->rev->to;
|
||||
}
|
||||
now = T;
|
||||
while(S != now)
|
||||
{
|
||||
cost += hist[now]->flow(m);
|
||||
now = hist[now]->rev->to;
|
||||
}
|
||||
ans += m;
|
||||
}
|
||||
return {ans, cost};
|
||||
}
|
||||
32
2024fall/source/Graph/TarjanSCC.cpp
Normal file
32
2024fall/source/Graph/TarjanSCC.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
vi adj[N];
|
||||
int in[N], c = 0;
|
||||
stack<int> p;
|
||||
bool fin[N]; int scn[N], nscc = 0;
|
||||
|
||||
int dfs(int s)
|
||||
{
|
||||
in[s] = ++c;
|
||||
p.push(s);
|
||||
|
||||
int m = c;
|
||||
for(auto i : adj[s])
|
||||
{
|
||||
if(in[i] == 0) m = min(m, dfs(i));
|
||||
else if(!fin[i]) m = min(m, in[i]);
|
||||
}
|
||||
|
||||
if(m == in[s])
|
||||
{
|
||||
nscc++;
|
||||
while(p.top() != s)
|
||||
{
|
||||
int i = p.top(); p.pop();
|
||||
scn[i] = nscc; fin[i] = true;
|
||||
}
|
||||
p.pop();
|
||||
scn[s] = nscc; fin[s] = true;
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
forr(i, n) if(!fin[i]) dfs(i);
|
||||
Reference in New Issue
Block a user