P3376 【模板】网络最大流
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=200+10,INF=0x3f3f3f3f;
int head[N];
struct e
{
int to;
ll f;
int ne;
} edge[10010];
void add(int u, int v, int f)
{
edge[++head[0]] = {v, f, head[u]};
head[u] = head[0];
edge[++head[0]] = {u, 0, head[v]};//反向边
head[v] = head[0];
}
int dep[N], cur[N];
bool bfs(int s,int t)
{
memset(dep, 0, sizeof dep);
memcpy(cur, head, sizeof cur);
queue<int> que;
que.emplace(s);
dep[s] = 1;
while(!que.empty())
{
int u = que.front();
que.pop();
for (int i = head[u]; i;i = edge[i].ne)
{
if(edge[i].f && !dep[edge[i].to])
{
dep[edge[i].to] = dep[u] + 1;
que.emplace(edge[i].to);
}
}
}
return dep[t];
}
ll dfs(int u ,int t, int f)
{
if(!f || u==t)
return f;
ll flow = 0;
for (int i = cur[u]; flow < f && i; i = edge[i].ne)
{
cur[u] = i;//弧优化
if(edge[i].f && dep[edge[i].to] == dep[u] + 1)
{
ll tmp = dfs(edge[i].to, t, min(f - flow, edge[i].f));
edge[i].f -= tmp;
edge[i ^ 1].f += tmp;//反向边
flow += tmp;
}
}
return flow;
}
ll dinic(int s, int t)
{
ll ans = 0;
while(bfs(s,t))//找增广路
{
ans += dfs(s, t, INF);
}
return ans;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
head[0] = 1;
int n, m, s, t;
cin >> n >> m >> s >> t;
for (int i = 1; i <= m;i++)
{
int u, v, f;
cin >> u >> v >> f;
add(u, v, f);
}
cout << dinic(s, t);
return 0;
}
P3381【模板】最小费用最大流
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=6e3+10,INF=0x3f3f3f3f;
const double eps=1e-8;
int head[N];
struct e
{
int to, f, c, ne;
} edge[N * 10 * 2];
int dis[N], pre[N], prv[N];//最小费用路径,前驱节点,前驱边
bool vis[N];
void add(int u, int v, int f,int c)
{
edge[++head[0]] = {v, f, c, head[u]};
head[u] = head[0];
edge[++head[0]] = {u, 0, -c, head[v]};
head[v] = head[0];
}
bool spfa(int s,int t)
{
queue<int> que;
que.emplace(s);
memset(dis, 0x3f, sizeof dis);
memset(vis, 0, sizeof vis);
dis[s] = 0;
vis[s] = 1;
while(!que.empty())
{
int u = que.front();
que.pop();
vis[u] = 0;
for (int i = head[u]; i;i = edge[i].ne)
{
int v = edge[i].to;
if(edge[i].f && dis[v] > dis[u] + edge[i].c)
{
dis[v] = dis[u] + edge[i].c;
prv[v] = u;
pre[v] = i;
if(!vis[v])
{
vis[v] = 1;
que.emplace(v);
}
}
}
}
return dis[t] != INF;
}
pii mcmf(int s,int t)//时间复杂度O(V^2 E^2),实际情况远小于理论时间复杂度
{
int cost = 0, flow = 0;
while(spfa(s,t))
{
int mn = INF;
for (int i = t; i != s; i = prv[i])
{
mn = min(mn, edge[pre[i]].f);
}
flow += mn;
cost += mn * dis[t];
for (int i = t; i != s;i = prv[i])
{
edge[pre[i]].f -= mn;
edge[pre[i] ^ 1].f += mn;//反向边
}
}
return {cost, flow};
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n, m, s, t;
cin >> n >> m >> s >> t;
head[0] = 1;
for (int i = 1; i <= m;i++)
{
int u, v, f, c;
cin >> u >> v >> f >> c;
add(u, v, f, c);
}
pii ans = mcmf(s, t);
cout << ans.second << ' ' << ans.first;
return 0;
}
P2756 飞行员配对方案问题
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=1e2+10,INF=0x3f3f3f3f;
const double eps=1e-8;
int head[N];
struct e
{
int to, f, ne;
}edge[N*N];
void add(int u, int v, int f)
{
edge[++head[0]] = {v, f, head[u]};
head[u] = head[0];
edge[++head[0]] = {u, 0, head[v]};//反向边
head[v] = head[0];
}
int dep[N], cur[N];
bool bfs(int s,int t)
{
memset(dep, 0, sizeof dep);
memcpy(cur, head, sizeof cur);
queue<int> que;
que.emplace(s);
dep[s] = 1;
while(!que.empty())
{
int u = que.front();
que.pop();
for (int i = head[u]; i;i = edge[i].ne)
{
if(edge[i].f && !dep[edge[i].to])
{
dep[edge[i].to] = dep[u] + 1;
que.emplace(edge[i].to);
}
}
}
return dep[t];
}
int dfs(int u ,int t, int f)
{
if(!f || u==t)
return f;
int flow = 0;
for (int i = cur[u]; flow < f && i; i = edge[i].ne)
{
cur[u] = i;//弧优化
if(edge[i].f && dep[edge[i].to] == dep[u] + 1)
{
int tmp = dfs(edge[i].to, t, min(f - flow, edge[i].f));
edge[i].f -= tmp;
edge[i ^ 1].f += tmp;//反向边
flow += tmp;
}
}
return flow;
}
int dinic(int s, int t)
{
int ans = 0;
while(bfs(s,t))//找增广路
{
ans += dfs(s, t, INF);
}
return ans;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n, m;
cin >> m >> n;
head[0] = 1;
int s = n + 1, t = n + 2;
int u, v;
for (int i = 1; i <= m;i++)
{
add(s, i, 1);
}
while(cin>>u>>v)
{
if(u==-1)
break;
add(u, v, 1);
}
for (int i = m + 1; i <= n;i++)
{
add(i, t, 1);
}
int ans = dinic(s, t);
cout << ans <<'\n';
for (int i = 1; i <= m;i++)
{
int v = 0;
for (int j = head[i]; j;j = edge[j].ne)
{
int to = edge[j].to;
if(to>m && to<=n && edge[j].f == 0)
{
v = to;
break;
}
}
if(v)
{
cout << i << " " << v << '\n';
}
}
return 0;
}
P3254 圆桌问题
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=500+10,INF=0x3f3f3f3f;
const double eps=1e-8;
int head[N];
struct e
{
int to, f, ne;
} edge[N*N];
void add(int u, int v, int f)
{
edge[++head[0]] = {v, f, head[u]};
head[u] = head[0];
edge[++head[0]] = {u, 0, head[v]};//反向边
head[v] = head[0];
}
int dep[N], cur[N];
bool bfs(int s,int t)
{
memset(dep, 0, sizeof dep);
memcpy(cur, head, sizeof cur);
queue<int> que;
que.emplace(s);
dep[s] = 1;
while(!que.empty())
{
int u = que.front();
que.pop();
for (int i = head[u]; i;i = edge[i].ne)
{
if(edge[i].f && !dep[edge[i].to])
{
dep[edge[i].to] = dep[u] + 1;
que.emplace(edge[i].to);
}
}
}
return dep[t];
}
int dfs(int u ,int t, int f)
{
if(!f || u==t)
return f;
int flow = 0;
for (int i = cur[u]; flow < f && i; i = edge[i].ne)
{
cur[u] = i;//弧优化
if(edge[i].f && dep[edge[i].to] == dep[u] + 1)
{
int tmp = dfs(edge[i].to, t, min(f - flow, edge[i].f));
edge[i].f -= tmp;
edge[i ^ 1].f += tmp;//反向边
flow += tmp;
}
}
return flow;
}
int dinic(int s, int t)
{
int ans = 0;
while(bfs(s,t))//找增广路
{
ans += dfs(s, t, INF);
}
return ans;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
head[0] = 1;
int n, m, s, t;
cin >> m >> n;
int sum = 0;
s = n + m + 1, t = s + 1;
for (int i = 1; i <= m;i++)
{
int num;
cin >> num;
sum += num;
add(s, i, num);
}
for (int i = 1; i <= n;i++)
{
int num;
cin >> num;
add(i + m, t, num);
for (int j = 1; j <= m;j++)
{
add(j, i + m, 1);
}
}
int ans = dinic(s, t);
if(ans!=sum)
{
cout << 0;
}
else
{
cout << 1 << '\n';
for (int i = 1; i <= m;i++)
{
int v = -1;
for (int j = head[i]; j;j = edge[j].ne)
{
if(edge[j].f==0&&edge[j].to<s)
{
cout << edge[j].to - m << ' ';
}
}
cout << '\n';
}
}
return 0;
}
P3171 [CQOI2015]网络吞吐量
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
#define endl '\n'
const int N = 2e3 + 10;
const ll INF = 1e18;
const double eps=1e-8;
int head[N];
struct e
{
int to;
ll f;
int ne;
} edge[200010];
void add(int u, int v, ll f)
{
edge[++head[0]] = {v, f, head[u]};
head[u] = head[0];
edge[++head[0]] = {u, 0, head[v]};//反向边
head[v] = head[0];
}
int dep[N], cur[N];
bool bfs(int s,int t)
{
memset(dep, 0, sizeof dep);
memcpy(cur, head, sizeof cur);
queue<int> que;
que.emplace(s);
dep[s] = 1;
while(!que.empty())
{
int u = que.front();
que.pop();
for (int i = head[u]; i;i = edge[i].ne)
{
if(edge[i].f && !dep[edge[i].to])
{
dep[edge[i].to] = dep[u] + 1;
que.emplace(edge[i].to);
}
}
}
return dep[t];
}
ll dfs(int u ,int t, ll f)
{
if(!f || u==t)
return f;
ll flow = 0;
for (int i = cur[u]; flow < f && i; i = edge[i].ne)
{
cur[u] = i;//弧优化
if(edge[i].f && dep[edge[i].to] == dep[u] + 1)
{
ll tmp = dfs(edge[i].to, t, min(f - flow, edge[i].f));
edge[i].f -= tmp;
edge[i ^ 1].f += tmp;//反向边
flow += tmp;
}
}
return flow;
}
ll dinic(int s, int t)
{
ll ans = 0;
while(bfs(s,t))//找增广路
{
ans += dfs(s, t, INF);
}
return ans;
}
bool vis[N];
ll dis[N];
vector<pair<int, ll>> p[N];
void spfa()
{
for (int i = 1; i < N;i++)
{
dis[i] = INF;
}
queue<int> que;
que.push(1);
dis[1] = 0;
vis[1] = 1;
while(!que.empty())
{
int t = que.front();
que.pop();
vis[t] = 0;
for(auto tt : p[t])
{
int j = tt.first;
ll w = tt.second;
if(dis[j] > dis[t] + w)
{
dis[j] = dis[t] + w;
if(!vis[j])
{
que.push(j);
vis[j] = 1;
}
}
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n, m;
cin >> n >> m;
head[0] = 1;
int s = n * 2 + 1;
int t = s + 1;
for (int i = 1; i <= m;i++)
{
int u, v;
ll f;
cin >> u >> v >> f;
p[u].push_back({v, f});
p[v].push_back({u, f});
}
spfa();
for (int i = 1; i <= n;i++)
{
ll f;
cin >> f;
if(i!=1&&i!=n)
add(i, i + n, f);//入 -> 出
else
add(i, i + n, INF);
}
add(s, 1, INF);
add(n + n, t, INF);
for (int i = 1; i <= n;i++)
{
for(auto t : p[i])
{
int j = t.first;
ll w = t.second;
if(dis[j] == dis[i] + w)
{
add(i + n, j, INF);
}
}
}
cout << dinic(s,t);
return 0;
}
P2766 最长不下降子序列问题
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=2000+10,INF=0x3f3f3f3f;
const double eps=1e-8;
int a[N],dp[N];
int head[N];
struct e
{
int to, f, ne;
} edge[N*N];
void add(int u, int v, int f)
{
edge[++head[0]] = {v, f, head[u]};
head[u] = head[0];
edge[++head[0]] = {u, 0, head[v]};//反向边
head[v] = head[0];
}
int dep[N], cur[N];
bool bfs(int s,int t)
{
memset(dep, 0, sizeof dep);
memcpy(cur, head, sizeof cur);
queue<int> que;
que.emplace(s);
dep[s] = 1;
while(!que.empty())
{
int u = que.front();
que.pop();
for (int i = head[u]; i;i = edge[i].ne)
{
if(edge[i].f && !dep[edge[i].to])
{
dep[edge[i].to] = dep[u] + 1;
que.emplace(edge[i].to);
}
}
}
return dep[t];
}
int dfs(int u ,int t, int f)
{
if(!f || u==t)
return f;
int flow = 0;
for (int i = cur[u]; flow < f && i; i = edge[i].ne)
{
cur[u] = i;//弧优化
if(edge[i].f && dep[edge[i].to] == dep[u] + 1)
{
int tmp = dfs(edge[i].to, t, min(f - flow, edge[i].f));
edge[i].f -= tmp;
edge[i ^ 1].f += tmp;//反向边
flow += tmp;
}
}
return flow;
}
int dinic(int s, int t)
{
static int ans = 0;
while(bfs(s,t))//找增广路
{
ans += dfs(s, t, INF);
}
return ans;
}
void init()
{
memset(head, 0, sizeof head);
head[0] = 1;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin >> n;
head[0] = 1;
for (int i = 1; i <= n;i++)
{
dp[i] = 1;
cin >> a[i];
}
for (int i = 1; i <= n;i++)
{
for (int j = 1; j < i;j++)
{
if(a[i]>=a[j])
dp[i] = max(dp[i],dp[j] + 1);
}
}
int len = 0;
for (int i = 1; i <= n;i++)
len = max(len, dp[i]);
cout << len << '\n';
int s = n*2 + 1, t = s + 1;
for (int i = 1; i <= n;i++)
{
if(dp[i]==len)
{
add(i+n, t, 1);
}
if(dp[i]==1)
{
add(s, i, 1);
}
add(i, i + n, 1);
}
for (int i = 1; i < n;i++)
{
for (int j = i + 1; j <= n;j++)
{
if((a[j] >= a[i])&&(dp[j] == dp[i] + 1))
add(i + n, j, 1);
}
}
cout << dinic(s, t) << '\n';
if(n==1)
{
cout << 1;
return 0;
}
add(s, 1, INF);
add(1, 1 + n, INF);
if (dp[n] == len)
add(n, n + n, INF), add(n + n, t, INF);
cout << dinic(s, t) << '\n';
return 0;
}
P5771 反质数序列
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
#define endl '\n'
const int N=3000+10,INF=0x3f3f3f3f;
const double eps=1e-8;
int head[N];
struct e
{
int to, f, ne;
} edge[N*N];
void add(int u, int v, int f)
{
edge[++head[0]] = {v, f, head[u]};
head[u] = head[0];
edge[++head[0]] = {u, 0, head[v]};//反向边
head[v] = head[0];
}
int dep[N], cur[N];
bool bfs(int s,int t)
{
memset(dep, 0, sizeof dep);
memcpy(cur, head, sizeof cur);
queue<int> que;
que.emplace(s);
dep[s] = 1;
while(!que.empty())
{
int u = que.front();
que.pop();
for (int i = head[u]; i;i = edge[i].ne)
{
if(edge[i].f && !dep[edge[i].to])
{
dep[edge[i].to] = dep[u] + 1;
que.emplace(edge[i].to);
}
}
}
return dep[t];
}
int dfs(int u ,int t, int f)
{
if(!f || u==t)
return f;
int flow = 0;
for (int i = cur[u]; flow < f && i; i = edge[i].ne)
{
cur[u] = i;//弧优化
if(edge[i].f && dep[edge[i].to] == dep[u] + 1)
{
int tmp = dfs(edge[i].to, t, min(f - flow, edge[i].f));
edge[i].f -= tmp;
edge[i ^ 1].f += tmp;//反向边
flow += tmp;
}
}
return flow;
}
int dinic(int s, int t)
{
int ans = 0;
while(bfs(s,t))//找增广路
{
ans += dfs(s, t, INF);
}
return ans;
}
void init()
{
memset(head, 0, sizeof head);
head[0] = 1;
}
vector<pii> odd, even;
bool prime(int x)
{
if(x == 2)
return 1;
for (int i = 2; i <= x / i;i++)
{
if(x % i==0)
return 0;
}
return 1;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin>>n;
head[0] = 1;
int ans = n, f = 0;
int s = n + 1, t = s + 1;
for (int i = 1; i <= n;i++)
{
int x;
cin >> x;
if(x == 1 && f)
{
ans--;
continue;
}
if(x == 1)
f = 1;
if(x&1)
odd.push_back({x, i}), add(s, i, 1);
else
even.push_back({x, i}),add(i, t, 1);
}
for (int i = 0; i < odd.size();i++)
{
for (int j = 0; j < even.size();j++)
{
if(prime(odd[i].first + even[j].first))
add(odd[i].second, even[j].second, INF);
}
}
cout << ans - dinic(s, t);
return 0;
}
P3163 危桥
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
#define endl '\n'
const int N=500+10,INF=0x3f3f3f3f;
const double eps=1e-8;
char a[55][55];
int head[N];
struct e
{
int to, f, ne;
} edge[N*N];
void add(int u, int v, int f)
{
edge[++head[0]] = {v, f, head[u]};
head[u] = head[0];
edge[++head[0]] = {u, 0, head[v]};//反向边
head[v] = head[0];
}
int dep[N], cur[N];
bool bfs(int s,int t)
{
memset(dep, 0, sizeof dep);
memcpy(cur, head, sizeof cur);
queue<int> que;
que.emplace(s);
dep[s] = 1;
while(!que.empty())
{
int u = que.front();
que.pop();
for (int i = head[u]; i;i = edge[i].ne)
{
if(edge[i].f && !dep[edge[i].to])
{
dep[edge[i].to] = dep[u] + 1;
que.emplace(edge[i].to);
}
}
}
return dep[t];
}
int dfs(int u ,int t, int f)
{
if(!f || u==t)
return f;
int flow = 0;
for (int i = cur[u]; flow < f && i; i = edge[i].ne)
{
cur[u] = i;//弧优化
if(edge[i].f && dep[edge[i].to] == dep[u] + 1)
{
int tmp = dfs(edge[i].to, t, min(f - flow, edge[i].f));
edge[i].f -= tmp;
edge[i ^ 1].f += tmp;//反向边
flow += tmp;
}
}
return flow;
}
int dinic(int s, int t)
{
int ans = 0;
while(bfs(s,t))//找增广路
{
ans += dfs(s, t, INF);
}
return ans;
}
void init()
{
memset(head, 0, sizeof head);
head[0] = 1;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n, a1, b1, a2, b2, an, bn;
while(cin>>n>>a1>>a2>>an>>b1>>b2>>bn)
{
init();
a1++, a2++, b1++, b2++;
for (int i = 1; i <= n;i++)
{
for (int j = 1; j <= n;j++)
{
cin >> a[i][j];
}
}
int s = n + 1;
int t = s + 1;
for (int i = 1; i <= n;i++)
{
for (int j = 1; j <= n;j++)
{
if(a[i][j]=='N')
add(i, j, INF);
if(a[i][j]=='O')
add(i, j, 2);
}
}
add(s, a1, 2*an);
add(s, b1, 2*bn);
add(a2, t, 2*an);
add(b2, t, 2*bn);
if (dinic(s, t) == 2 * (an + bn))
{
init();
swap(b1, b2);
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
if (a[i][j] == 'N')
add(i, j, INF);
if (a[i][j] == 'O')
add(i, j, 2);
}
}
add(s, a1, 2 * an);
add(s, b1, 2 * bn);
add(a2, t, 2 * an);
add(b2, t, 2 * bn);
if (dinic(s, t) == 2 * (an + bn))
cout << "Yes\n";
else
cout << "No\n";
}
else
cout << "No\n";
}
return 0;
}
P5038 奇怪的游戏
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
#define endl '\n'
#define int ll
#define INF 9e18
const int N = 1600 + 10;
const double eps=1e-8;
int head[N];
int n, m, S, T;
struct e
{
int to;
int f;
int ne;
} edge[10*N*N];
void add(int u, int v, int f)
{
edge[++head[0]] = {v, f, head[u]};
head[u] = head[0];
edge[++head[0]] = {u, 0, head[v]};//反向边
head[v] = head[0];
}
int dep[N], cur[N];
bool bfs(int s,int t)
{
memset(dep, 0, sizeof dep);
memcpy(cur, head, sizeof cur);
queue<int> que;
que.emplace(s);
dep[s] = 1;
while(!que.empty())
{
int u = que.front();
que.pop();
for (int i = head[u]; i;i = edge[i].ne)
{
if(edge[i].f && !dep[edge[i].to])
{
dep[edge[i].to] = dep[u] + 1;
que.emplace(edge[i].to);
}
}
}
return dep[t];
}
int dfs(int u ,int t, int f)
{
if(!f || u==t)
return f;
int flow = 0;
for (int i = cur[u]; flow < f && i; i = edge[i].ne)
{
cur[u] = i;//弧优化
if(edge[i].f && dep[edge[i].to] == dep[u] + 1)
{
int tmp = dfs(edge[i].to, t, min(f - flow, edge[i].f));
edge[i].f -= tmp;
edge[i ^ 1].f += tmp;//反向边
flow += tmp;
}
}
return flow;
}
int dinic(int s, int t)
{
int ans = 0;
while(bfs(s,t))//找增广路
{
ans += dfs(s, t, INF);
}
return ans;
}
void init()
{
memset(head, 0, sizeof head);
head[0] = 1;
}
int a[50][50];
int dx[] = {1, -1, 0, 0}, dy[] = {0, 0, 1, -1};
bool check(int mid)
{
init();
int res = 0;
for (int i = 1;i<=n;i++)
{
for (int j = 1; j <= m;j++)
{
if((i + j&1))
{
add(S, (i - 1) * m + j, mid - a[i][j]);
for (int k = 0; k < 4;k++)
{
int x = i + dx[k];
int y = j + dy[k];
if(x>=1&&x<=n&&y>=1&&y<=m)
{
add((i - 1) * m + j, (x - 1) * m + y, INF);
}
}
}
else
{
add((i - 1) * m + j, T, mid - a[i][j]);
res += mid - a[i][j];
}
}
}
return dinic(S,T) == res;
}
signed main()
{
// ios::sync_with_stdio(false);
// cin.tie(0);
int t;
cin >> t;
while(t--)
{
init();
scanf("%lld%lld", &n, &m);
int sum1 = 0, sum2 = 0;
int cnt1 = 0, cnt2 = 0;
S = n*m+1, T = S + 1;
int mmax = -1;
for (int i = 1; i <= n;i++)
{
for (int j = 1; j <= m;j++)
{
scanf("%lld", &a[i][j]);
if ((i + j) & 1)
sum1 += a[i][j], cnt1++;
else
sum2 += a[i][j], cnt2++;
mmax = max(a[i][j], mmax);
}
}
if((n*m)%2==0)
{
if(sum1!=sum2)
{
printf("-1\n");
continue;
}
int l = mmax, r = 10 * mmax;
while(l < r)
{
int mid = l + r >> 1;
if(check(mid))
r = mid;
else
l = mid + 1;
}
if(!check(r))
{
printf("-1\n");
continue;
}
int ans = 0;
for (int i = 1; i <= n;i++)
{
for (int j = 1; j <= m;j++)
{
ans += r - a[i][j];
}
}
printf("%lld\n",ans / 2);
}
else
{
if((sum2 - sum1)%(cnt2 - cnt1))
{
printf("-1\n");
continue;
}
int x = (sum2 - sum1) / (cnt2 - cnt1);
if(x < mmax)
{
printf("-1\n");
continue;
}
if(check(x))
{
printf("%lld\n", x * cnt1 - sum1);
}
else
printf("-1\n");
}
}
return 0;
}
P4016 负载平衡问题
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=200+10,INF=0x3f3f3f3f;
const double eps=1e-8;
int a[N];
int head[N];
struct e
{
int to, f, c, ne;
} edge[N * 10 * 2];
int dis[N], pre[N], prv[N];//最小费用路径,前驱节点,前驱边
bool vis[N];
void add(int u, int v, int f,int c)
{
edge[++head[0]] = {v, f, c, head[u]};
head[u] = head[0];
edge[++head[0]] = {u, 0, -c, head[v]};
head[v] = head[0];
}
bool spfa(int s,int t)
{
queue<int> que;
que.emplace(s);
memset(dis, 0x3f, sizeof dis);
memset(vis, 0, sizeof vis);
dis[s] = 0;
vis[s] = 1;
while(!que.empty())
{
int u = que.front();
que.pop();
vis[u] = 0;
for (int i = head[u]; i;i = edge[i].ne)
{
int v = edge[i].to;
if(edge[i].f && dis[v] > dis[u] + edge[i].c)
{
dis[v] = dis[u] + edge[i].c;
prv[v] = u;
pre[v] = i;
if(!vis[v])
{
vis[v] = 1;
que.emplace(v);
}
}
}
}
return dis[t] != INF;
}
pii mcmf(int s,int t)//时间复杂度O(V^2 E^2),实际情况远小于理论时间复杂度
{
int cost = 0, flow = 0;
while(spfa(s,t))
{
int mn = INF;
for (int i = t; i != s; i = prv[i])
{
mn = min(mn, edge[pre[i]].f);
}
flow += mn;
cost += mn * dis[t];
for (int i = t; i != s;i = prv[i])
{
edge[pre[i]].f -= mn;
edge[pre[i] ^ 1].f += mn;//反向边
}
}
return {cost, flow};
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
head[0] = 1;
int n;
cin >> n;
int s = n + 1, t = s + 1;
int sum = 0;
for (int i = 1; i <= n;i++)
{
cin >> a[i];
sum += a[i];
add(s, i, a[i], 0);
}
int ave = sum / n;
for (int i = 1; i <= n;i++)
{
add(i, t, ave, 0);
if(i-1>0)
{
add(i, i - 1, INF, 1);
}
if(i+1<=n)
{
add(i, i + 1, INF, 1);
}
}
add(1, n, INF, 1);
add(n, 1, INF, 1);
cout << mcmf(s, t).first;
return 0;
}
P4015 运输问题
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=100+10,INF=0x3f3f3f3f;
const double eps=1e-8;
int a[N],b[N],c[N][N];
int head[N];
struct e
{
int to, f, c, ne;
} edge[N * 10 * 2];
int dis[N], pre[N], prv[N];//最小费用路径,前驱节点,前驱边
bool vis[N];
void add(int u, int v, int f, int c)
{
edge[++head[0]] = {v, f, c, head[u]};
head[u] = head[0];
edge[++head[0]] = {u, 0, -c, head[v]};
head[v] = head[0];
}
bool spfa(int s,int t)
{
queue<int> que;
que.emplace(s);
memset(dis, 0x3f, sizeof dis);
memset(vis, 0, sizeof vis);
dis[s] = 0;
vis[s] = 1;
while(!que.empty())
{
int u = que.front();
que.pop();
vis[u] = 0;
for (int i = head[u]; i;i = edge[i].ne)
{
int v = edge[i].to;
if(edge[i].f && dis[v] > dis[u] + edge[i].c)
{
dis[v] = dis[u] + edge[i].c;
prv[v] = u;
pre[v] = i;
if(!vis[v])
{
vis[v] = 1;
que.emplace(v);
}
}
}
}
return dis[t] != INF;
}
pii mcmf(int s,int t)//时间复杂度O(V^2 E^2),实际情况远小于理论时间复杂度
{
int cost = 0, flow = 0;
while(spfa(s,t))
{
int mn = INF;
for (int i = t; i != s; i = prv[i])
{
mn = min(mn, edge[pre[i]].f);
}
flow += mn;
cost += mn * dis[t];
for (int i = t; i != s;i = prv[i])
{
edge[pre[i]].f -= mn;
edge[pre[i] ^ 1].f += mn;//反向边
}
}
return {cost, flow};
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
head[0] = 1;
int m, n;
cin >> m >> n;
int s = m + n + 1, t = s + 1;
for (int i = 1; i <= m;i++)
{
cin >> a[i];
add(s, i, a[i], 0);
}
for (int i = 1; i <= n;i++)
{
cin >> b[i];
add(i + m, t, b[i], 0);
}
for (int i = 1; i <= m;i++)
{
for (int j = 1; j <= n;j++)
{
cin >> c[i][j];
add(i, j + m, INF, c[i][j]);
}
}
cout << mcmf(s, t).first << '\n';
memset(head, 0, sizeof head);
memset(pre, 0, sizeof pre);
memset(prv, 0, sizeof prv);
head[0] = 1;
for (int i = 1; i <= m;i++)
{
add(s, i, a[i], 0);
}
for (int i = 1; i <= n;i++)
{
add(i + m, t, b[i], 0);
}
for (int i = 1; i <= m;i++)
{
for (int j = 1; j <= n;j++)
{
add(i, j + m, INF, -c[i][j]);
}
}
cout << -mcmf(s, t).first;
return 0;
}
P1251 餐巾计划问题
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=4000+10,INF=0x3f3f3f3f;
const double eps=1e-8;
int head[N];
int a[N];
struct e
{
int to, f, c, ne;
} edge[N * 10 * 2];
int dis[N], pre[N], prv[N];//最小费用路径,前驱节点,前驱边
bool vis[N];
void add(int u, int v, int f, int c)
{
edge[++head[0]] = {v, f, c, head[u]};
head[u] = head[0];
edge[++head[0]] = {u, 0, -c, head[v]};
head[v] = head[0];
}
bool spfa(int s,int t)
{
queue<int> que;
que.emplace(s);
memset(dis, 0x3f, sizeof dis);
memset(vis, 0, sizeof vis);
dis[s] = 0;
vis[s] = 1;
while(!que.empty())
{
int u = que.front();
que.pop();
vis[u] = 0;
for (int i = head[u]; i;i = edge[i].ne)
{
int v = edge[i].to;
if(edge[i].f && dis[v] > dis[u] + edge[i].c)
{
dis[v] = dis[u] + edge[i].c;
prv[v] = u;
pre[v] = i;
if(!vis[v])
{
vis[v] = 1;
que.emplace(v);
}
}
}
}
return dis[t] != INF;
}
ll mcmf(int s,int t)//时间复杂度O(V^2 E^2),实际情况远小于理论时间复杂度
{
ll cost = 0;
while(spfa(s,t))
{
int mn = INF;
for (int i = t; i != s; i = prv[i])
{
mn = min(mn, edge[pre[i]].f);
}
cost += 1ll*mn * dis[t];
for (int i = t; i != s;i = prv[i])
{
edge[pre[i]].f -= mn;
edge[pre[i] ^ 1].f += mn;//反向边
}
}
return cost;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
head[0] = 1;
int n;
cin>>n;
for (int i = 1; i <= n;i++)
{
cin >> a[i];
}
int s = n * 2 + 1, t = s + 1;
int p, m, f, n1, s1;
cin >> p >> m >> f >> n1 >> s1;
for (int i = 1; i <= n;i++)
{
add(s, i, INF, p);
add(i, t, a[i], 0);
add(s, i + n, a[i], 0);
if(i+m<=n)
add(i + n, i + m, INF, f);
if(i+n1<=n)
add(i + n, i + n1, INF, s1);
if(i!=n)
add(i + n, i + n + 1, INF, 0);
}
cout << mcmf(s, t);
return 0;
}
P4013 数字梯形问题
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=2000+10,INF=0x3f3f3f3f;
const double eps=1e-8;
int a[N][N],id[N][N];
int head[N];
struct e
{
int to, f, c, ne;
} edge[N * 10 * 2];
int dis[N], pre[N], prv[N];//最小费用路径,前驱节点,前驱边
bool vis[N];
void add(int u, int v, int f, int c)
{
edge[++head[0]] = {v, f, c, head[u]};
head[u] = head[0];
edge[++head[0]] = {u, 0, -c, head[v]};
head[v] = head[0];
}
bool spfa(int s,int t)
{
queue<int> que;
que.emplace(s);
memset(dis, 0x3f, sizeof dis);
memset(vis, 0, sizeof vis);
dis[s] = 0;
vis[s] = 1;
while(!que.empty())
{
int u = que.front();
que.pop();
vis[u] = 0;
for (int i = head[u]; i;i = edge[i].ne)
{
int v = edge[i].to;
if(edge[i].f && dis[v] > dis[u] + edge[i].c)
{
dis[v] = dis[u] + edge[i].c;
prv[v] = u;
pre[v] = i;
if(!vis[v])
{
vis[v] = 1;
que.emplace(v);
}
}
}
}
return dis[t] != INF;
}
int mcmf(int s,int t)//时间复杂度O(V^2 E^2),实际情况远小于理论时间复杂度
{
int cost = 0, flow = 0;
while(spfa(s,t))
{
int mn = INF;
for (int i = t; i != s; i = prv[i])
{
mn = min(mn, edge[pre[i]].f);
}
flow += mn;
cost += mn * dis[t];
for (int i = t; i != s;i = prv[i])
{
edge[pre[i]].f -= mn;
edge[pre[i] ^ 1].f += mn;//反向边
}
}
return cost;
}
void init()
{
memset(head, 0, sizeof head);
memset(pre, 0, sizeof pre);
memset(prv, 0, sizeof prv);
head[0] = 1;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int m,n;
cin>>m>>n;
int sum = 0;
int s, t;
head[0] = 1;
for (int i = 1; i <= n;i++)
{
for (int j = 1; j <= m + i - 1;j++)
{
cin>>a[i][j];
id[i][j]=++sum;
}
}
s = sum*2 + 1, t = s + 1;
for (int i = 1; i < n;i++)
{
for (int j = 1; j <= m + i - 1;j++)
{
if(i==1)
add(s, id[i][j], 1, 0);
add(id[i][j], id[i][j] + sum, 1, -a[i][j]);
add(id[i][j] + sum, id[i + 1][j], 1, 0);
add(id[i][j] + sum, id[i + 1][j + 1], 1, 0);
}
}
for (int j = 1; j <= m + n - 1;j++)
{
add(id[n][j] + sum, t, 1, 0);
add(id[n][j], id[n][j] + sum, 1, -a[n][j]);
}
cout << -mcmf(s, t) << '\n';
init();
s = sum + 1, t = s + 1;
for (int i = 1; i < n;i++)
{
for (int j = 1; j <= m + i - 1;j++)
{
if(i==1)
add(s, id[i][j], 1, 0);
add(id[i][j], id[i + 1][j], 1, -a[i][j]);
add(id[i][j], id[i + 1][j + 1], 1, -a[i][j]);
}
}
for (int j = 1; j <= m + n - 1;j++)
{
add(id[n][j], t, INF, -a[n][j]);
}
cout << -mcmf(s, t) << '\n';
init();
s = sum + 1, t = s + 1;
for (int i = 1; i < n;i++)
{
for (int j = 1; j <= m + i - 1;j++)
{
if(i==1)
add(s, id[i][j], 1, 0);
add(id[i][j], id[i + 1][j], INF, -a[i][j]);
add(id[i][j], id[i + 1][j + 1], INF, -a[i][j]);
}
}
for (int j = 1; j <= m + n - 1;j++)
{
add(id[n][j], t, INF, -a[n][j]);
}
cout << -mcmf(s, t) << '\n';
return 0;
}
P3356 火星探险问题
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 3000 + 10, INF = 0x3f3f3f3f;
const double eps = 1e-8;
int head[N], a[40][40], id[40][40], s, t;
int n, p, q;
struct e
{
int to, f, c, ne;
} edge[N * 10 * 2];
int dis[N], pre[N], prv[N]; //最小费用路径,前驱节点,前驱边
bool vis[N];
void add(int u, int v, int f, int c)
{
edge[++head[0]] = {v, f, c, head[u]};
head[u] = head[0];
edge[++head[0]] = {u, 0, -c, head[v]};
head[v] = head[0];
}
bool spfa(int s, int t)
{
queue<int> que;
que.emplace(s);
memset(dis, 0x3f, sizeof dis);
memset(vis, 0, sizeof vis);
dis[s] = 0;
vis[s] = 1;
while (!que.empty())
{
int u = que.front();
que.pop();
vis[u] = 0;
for (int i = head[u]; i; i = edge[i].ne)
{
int v = edge[i].to;
if (edge[i].f && dis[v] > dis[u] + edge[i].c)
{
dis[v] = dis[u] + edge[i].c;
prv[v] = u;
pre[v] = i;
if (!vis[v])
{
vis[v] = 1;
que.emplace(v);
}
}
}
}
return dis[t] != INF;
}
pii mcmf(int s, int t) //时间复杂度O(V^2 E^2),实际情况远小于理论时间复杂度
{
int cost = 0, flow = 0;
while (spfa(s, t))
{
int mn = INF;
for (int i = t; i != s; i = prv[i])
{
mn = min(mn, edge[pre[i]].f);
}
flow += mn;
cost += mn * dis[t];
for (int i = t; i != s; i = prv[i])
{
edge[pre[i]].f -= mn;
edge[pre[i] ^ 1].f += mn; //反向边
}
}
return {cost,flow};
}
void print(int x, int y, int u, int k)
{
int dx, dy, mov;
for (int i = head[u]; i;i = edge[i].ne)
{
int to = edge[i].to;
if(to == s||to == t||to == u - p*q||edge[i^1].f==0)
continue;
edge[i ^ 1].f--;
if(to>p*q)
{
print(x, y, to, k);
return;
}
if(to == id[x][y] + 1)
{
dx = x;
dy = y + 1;
mov = 1;
}
else
dx = x + 1, dy = y, mov = 0;
cout << k << ' ' << mov << '\n';
print(dx, dy, to + p * q, k);
return;
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
head[0] = 1;
cin >> n >> q >> p;
int sum = 0;
for (int i = 1; i <= p; i++)
{
for (int j = 1; j <= q; j++)
{
cin >> a[i][j];
id[i][j] = ++sum;
}
}
for (int i = 1; i <= p; i++)
{
for (int j = 1; j <= q; j++)
{
if (a[i][j] == 1)
continue;
if (a[i][j] == 2)
{
add(id[i][j], id[i][j] + sum, 1, -1); //拆点
}
add(id[i][j], id[i][j] + sum, INF, 0);
if (i < p && a[i + 1][j] != 1)
add(id[i][j] + sum, id[i + 1][j], INF, 0);
if (j < q && a[i][j + 1] != 1)
add(id[i][j] + sum, id[i][j + 1], INF, 0);
}
}
s = sum * 2 + 1, t = s + 1;
add(s, 1, n, 0);
add(id[p][q] + sum, t, n, 0);
pii ans = mcmf(s, t);
int flow = ans.second;
for (int i = 1; i <= flow; i++)
{
print(1, 1, 1, i);
}
return 0;
}
P2774 方格取数问题
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=1e4+10,INF=0x3f3f3f3f;
const double eps=1e-8;
int a[105][105],id[105][105], dx[]={1,-1,0,0},dy[]={0,0,1,-1};
int n, m;
bool check(int x,int y)
{
return x >= 1 && x <= n && y >= 1 && y <= m;
}
int head[N];
struct e
{
int to, f, ne;
} edge[N*N];
void add(int u, int v, int f)
{
edge[++head[0]] = {v, f, head[u]};
head[u] = head[0];
edge[++head[0]] = {u, 0, head[v]};//反向边
head[v] = head[0];
}
int dep[N], cur[N];
bool bfs(int s,int t)
{
memset(dep, 0, sizeof dep);
memcpy(cur, head, sizeof cur);
queue<int> que;
que.emplace(s);
dep[s] = 1;
while(!que.empty())
{
int u = que.front();
que.pop();
for (int i = head[u]; i;i = edge[i].ne)
{
if(edge[i].f && !dep[edge[i].to])
{
dep[edge[i].to] = dep[u] + 1;
que.emplace(edge[i].to);
}
}
}
return dep[t];
}
int dfs(int u ,int t, int f)
{
if(!f || u==t)
return f;
int flow = 0;
for (int i = cur[u]; flow < f && i; i = edge[i].ne)
{
cur[u] = i;//弧优化
if(edge[i].f && dep[edge[i].to] == dep[u] + 1)
{
int tmp = dfs(edge[i].to, t, min(f - flow, edge[i].f));
edge[i].f -= tmp;
edge[i ^ 1].f += tmp;//反向边
flow += tmp;
}
}
return flow;
}
int dinic(int s, int t)
{
int ans = 0;
while(bfs(s,t))//找增广路
{
ans += dfs(s, t, INF);
}
return ans;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n >> m;
int sum = 0;
int cnt = 0;
head[0] = 1;
for (int i = 1; i <= n;i++)
{
for (int j = 1; j <= m;j++)
{
cin >> a[i][j];
sum += a[i][j];
id[i][j] = ++cnt;
}
}
int s = n*m + 1, t = s + 1;
for (int i = 1;i<=n;i++)
{
for (int j = 1; j <= m;j++)
{
if((i+j)%2==0)
{
add(s, id[i][j], a[i][j]);
for (int k = 0; k < 4;k++)
{
int x = i + dx[k];
int y = j + dy[k];
if(check(x,y))
{
add(id[i][j], id[x][y], INF);
}
}
}
else
{
add(id[i][j], t, a[i][j]);
}
}
}
int ans = dinic(s, t);
cout << sum - ans;
return 0;
}
P3355 骑士共存问题
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=4e4+10,INF=0x3f3f3f3f;
const double eps=1e-8;
int a[205][205],id[205][205], dx[]={1,1,-1,-1,2,2,-2,-2},dy[]={2,-2,2,-2,1,-1,1,-1};
int n, m;
bool check(int x,int y)
{
return x >= 1 && x <= n && y >= 1 && y <= n;
}
int head[N];
struct e
{
int to, f, ne;
} edge[N*1000];
void add(int u, int v, int f)
{
edge[++head[0]] = {v, f, head[u]};
head[u] = head[0];
edge[++head[0]] = {u, 0, head[v]};//反向边
head[v] = head[0];
}
int dep[N], cur[N];
bool bfs(int s,int t)
{
memset(dep, 0, sizeof dep);
memcpy(cur, head, sizeof cur);
queue<int> que;
que.emplace(s);
dep[s] = 1;
while(!que.empty())
{
int u = que.front();
que.pop();
for (int i = head[u]; i;i = edge[i].ne)
{
if(edge[i].f && !dep[edge[i].to])
{
dep[edge[i].to] = dep[u] + 1;
que.emplace(edge[i].to);
}
}
}
return dep[t];
}
int dfs(int u ,int t, int f)
{
if(!f || u==t)
return f;
int flow = 0;
for (int i = cur[u]; flow < f && i; i = edge[i].ne)
{
cur[u] = i;//弧优化
if(edge[i].f && dep[edge[i].to] == dep[u] + 1)
{
int tmp = dfs(edge[i].to, t, min(f - flow, edge[i].f));
edge[i].f -= tmp;
edge[i ^ 1].f += tmp;//反向边
flow += tmp;
}
}
return flow;
}
int dinic(int s, int t)
{
int ans = 0;
while(bfs(s,t))//找增广路
{
ans += dfs(s, t, INF);
}
return ans;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n >> m;
int sum = n * n;
int cnt = 0;
head[0] = 1;
for (int i = 1; i <= m;i++)
{
int x, y;
cin >> x >> y;
a[x][y] = 1;
}
for (int i = 1; i <= n;i++)
{
for (int j = 1; j <= n;j++)
{
id[i][j] = ++cnt;
}
}
int s = n*n + 1, t = s + 1;
for (int i = 1;i<=n;i++)
{
for (int j = 1; j <= n;j++)
{
if(a[i][j])
continue;
if((i+j)&1)
{
add(s, id[i][j], 1);
for (int k = 0; k < 8;k++)
{
int x = i + dx[k];
int y = j + dy[k];
if(check(x,y)&&!a[x][y])
{
add(id[i][j], id[x][y], INF);
}
}
}
else
{
add(id[i][j], t, 1);
}
}
}
int ans = dinic(s, t);
cout << sum - ans - m;
return 0;
}
P2765 魔术球问题
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
#define endl '\n'
const int N=10000+10,INF=0x3f3f3f3f;
const double eps=1e-8;
int head[N], s, t, n;
bool vis[N];
struct e
{
int to, f, ne;
} edge[N*N];
void add(int u, int v, int f)
{
edge[++head[0]] = {v, f, head[u]};
head[u] = head[0];
edge[++head[0]] = {u, 0, head[v]};//反向边
head[v] = head[0];
}
int dep[N], cur[N];
bool bfs(int s,int t)
{
memset(dep, 0, sizeof dep);
memcpy(cur, head, sizeof cur);
queue<int> que;
que.emplace(s);
dep[s] = 1;
while(!que.empty())
{
int u = que.front();
que.pop();
for (int i = head[u]; i;i = edge[i].ne)
{
if(edge[i].f && !dep[edge[i].to])
{
dep[edge[i].to] = dep[u] + 1;
que.emplace(edge[i].to);
}
}
}
return dep[t];
}
int dfs(int u ,int t, int f)
{
if(!f || u==t)
return f;
int flow = 0;
for (int i = cur[u]; flow < f && i; i = edge[i].ne)
{
cur[u] = i;//弧优化
if(edge[i].f && dep[edge[i].to] == dep[u] + 1)
{
int tmp = dfs(edge[i].to, t, min(f - flow, edge[i].f));
edge[i].f -= tmp;
edge[i ^ 1].f += tmp;//反向边
flow += tmp;
}
}
return flow;
}
int dinic(int s, int t)
{
static int ans = 0;
while(bfs(s,t))//找增广路
{
ans += dfs(s, t, INF);
}
return ans;
}
void print(int x)
{
vis[x] = 1;
cout << x << ' ';
for (int i = head[x]; i;i = edge[i].ne)
{
int to = edge[i].to;
int f = edge[i].f;
if(!f&&to!=s&&to>n&&to!=t&to!=s)
{
print(to - 5000);
break;
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n;
int cnt = 0;
head[0] = 1;
vector<int> nums;
int pos = 0;
s = 5000 + 1;
t = s + 1;
int ans = 1;
int num = 0;
while(cnt <= n)
{
pos++;
add(s, pos, 1);
add(pos + 5000, t, 1);
for (int i = 0; i < nums.size();i++)
{
int res = sqrt(nums[i] + pos);
if((res * res) == (nums[i] + pos))
{
add(nums[i], pos + 5000, 1);
}
}
nums.push_back(pos);
//cout << dinic(s, t) << '\n';
int res = dinic(s, t);
if(res == ans)
{
cnt++;
}
ans = res;
}
cout << pos - 1 << '\n';
for (int i = 1; i <= pos - 1;i++)
{
if(!vis[i])
{
print(i);
cout << '\n';
}
}
return 0;
}
P2057 善意的投票
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
#define endl '\n'
const int N=500+10,INF=0x3f3f3f3f;
const double eps=1e-8;
int head[N];
struct e
{
int to, f, ne;
} edge[N*N];
void add(int u, int v, int f)
{
edge[++head[0]] = {v, f, head[u]};
head[u] = head[0];
edge[++head[0]] = {u, 0, head[v]};//反向边
head[v] = head[0];
}
int dep[N], cur[N];
bool bfs(int s,int t)
{
memset(dep, 0, sizeof dep);
memcpy(cur, head, sizeof cur);
queue<int> que;
que.emplace(s);
dep[s] = 1;
while(!que.empty())
{
int u = que.front();
que.pop();
for (int i = head[u]; i;i = edge[i].ne)
{
if(edge[i].f && !dep[edge[i].to])
{
dep[edge[i].to] = dep[u] + 1;
que.emplace(edge[i].to);
}
}
}
return dep[t];
}
int dfs(int u ,int t, int f)
{
if(!f || u==t)
return f;
int flow = 0;
for (int i = cur[u]; flow < f && i; i = edge[i].ne)
{
cur[u] = i;//弧优化
if(edge[i].f && dep[edge[i].to] == dep[u] + 1)
{
int tmp = dfs(edge[i].to, t, min(f - flow, edge[i].f));
edge[i].f -= tmp;
edge[i ^ 1].f += tmp;//反向边
flow += tmp;
}
}
return flow;
}
int dinic(int s, int t)
{
int ans = 0;
while(bfs(s,t))//找增广路
{
ans += dfs(s, t, INF);
}
return ans;
}
void init()
{
memset(head, 0, sizeof head);
head[0] = 1;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n, m;
cin >> n >> m;
head[0] = 1;
int s = n + 1;
int t = s + 1;
for (int i = 1; i <= n;i++)
{
int x;
cin>>x;
if(x)
add(s, i, 1);
else
add(i, t, 1);
}
for (int i = 1; i <= m; i++)
{
int x, y;
cin >> x >> y;
add(x, y, 1);
add(y, x, 1);
}
cout << dinic(s, t);
return 0;
}
P4174 最大获利
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
#define endl '\n'
const int N=55000+10,INF=0x3f3f3f3f;
const double eps=1e-8;
int head[N];
struct e
{
int to, f, ne;
} edge[10*N];
void add(int u, int v, int f)
{
edge[++head[0]] = {v, f, head[u]};
head[u] = head[0];
edge[++head[0]] = {u, 0, head[v]};//反向边
head[v] = head[0];
}
int dep[N], cur[N];
bool bfs(int s,int t)
{
memset(dep, 0, sizeof dep);
memcpy(cur, head, sizeof cur);
queue<int> que;
que.emplace(s);
dep[s] = 1;
while(!que.empty())
{
int u = que.front();
que.pop();
for (int i = head[u]; i;i = edge[i].ne)
{
if(edge[i].f && !dep[edge[i].to])
{
dep[edge[i].to] = dep[u] + 1;
que.emplace(edge[i].to);
}
}
}
return dep[t];
}
int dfs(int u ,int t, int f)
{
if(!f || u==t)
return f;
int flow = 0;
for (int i = cur[u]; flow < f && i; i = edge[i].ne)
{
cur[u] = i;//弧优化
if(edge[i].f && dep[edge[i].to] == dep[u] + 1)
{
int tmp = dfs(edge[i].to, t, min(f - flow, edge[i].f));
edge[i].f -= tmp;
edge[i ^ 1].f += tmp;//反向边
flow += tmp;
}
}
return flow;
}
int dinic(int s, int t)
{
int ans = 0;
while(bfs(s,t))//找增广路
{
ans += dfs(s, t, INF);
}
return ans;
}
void init()
{
memset(head, 0, sizeof head);
head[0] = 1;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n, m;
head[0] = 1;
cin >> n >> m;
int s = n + m + 1;
int t = s + 1;
for (int i = 1; i <= n;i++)
{
int x;
cin >> x;
add(s, i, x);
}
int sum = 0;
for (int i = 1; i <= m;i++)
{
int u, v, w;
cin >> u >> v >> w;
sum += w;
add(u, i + n, INF);
add(v, i + n, INF);
add(i + n, t, w);
}
cout << sum - dinic(s, t);
return 0;
}
P2764 最小路径覆盖问题
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
#define endl '\n'
const int N=300+10,INF=0x3f3f3f3f;
const double eps=1e-8;
int head[N],fa[N],vis[N];
int n, m, s, t;
struct e
{
int to, f, ne;
} edge[N*N];
void add(int u, int v, int f)
{
edge[++head[0]] = {v, f, head[u]};
head[u] = head[0];
edge[++head[0]] = {u, 0, head[v]};//反向边
head[v] = head[0];
}
int dep[N], cur[N];
bool bfs(int s,int t)
{
memset(dep, 0, sizeof dep);
memcpy(cur, head, sizeof cur);
queue<int> que;
que.emplace(s);
dep[s] = 1;
while(!que.empty())
{
int u = que.front();
que.pop();
for (int i = head[u]; i;i = edge[i].ne)
{
if(edge[i].f && !dep[edge[i].to])
{
dep[edge[i].to] = dep[u] + 1;
que.emplace(edge[i].to);
}
}
}
return dep[t];
}
int dfs(int u ,int t, int f)
{
if(!f || u==t)
return f;
int flow = 0;
for (int i = cur[u]; flow < f && i; i = edge[i].ne)
{
cur[u] = i;//弧优化
if(edge[i].f && dep[edge[i].to] == dep[u] + 1)
{
int tmp = dfs(edge[i].to, t, min(f - flow, edge[i].f));
edge[i].f -= tmp;
edge[i ^ 1].f += tmp;//反向边
flow += tmp;
}
}
return flow;
}
int dinic(int s, int t)
{
int ans = 0;
while(bfs(s,t))//找增广路
{
ans += dfs(s, t, INF);
}
return ans;
}
void print(int x)
{
vis[x] = 1;
cout << x << ' ';
for (int j = head[x]; j;j = edge[j].ne)
{
int to = edge[j].to;
int f = edge[j].f;
if(!f&&to!=t&&to!=s&&!vis[to - n])
{
print(to - n);
break;
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n>>m;
s = (n << 1) + 1;
t = s + 1;
head[0] = 1;
for (int i = 1; i <= n;i++)
{
add(s, i, 1);
add(i + n, t, 1);
}
for (int i = 1; i <= m;i++)
{
int a,b;
cin>>a>>b;
add(a, b + n, 1);
}
int ans = n - dinic(s, t);
for (int i = 1; i <= n;i++)
{
if(!vis[i])
{
print(i);
cout << '\n';
}
}
cout << ans;
return 0;
}