总结-网络流24题
马上就国庆了,翻了就是初赛。偶有怠惰,是复习联赛略枯燥的故。于是挖新坑,刷刷有趣的算法自慰。(肯定不会咕咕咕的啦,吧)
飞行员配对方案问题
输出方案数
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#define R(a,b,c) for(register int a = (b); (a) <= (c); ++(a))
#define nR(a,b,c) for(register int a = (b); (a) >= (c); --(a))
#define Fill(a,b) memset(a, b, sizeof(a))
#define Swap(a,b) ((a) ^= (b) ^= (a) ^= (b))
#define ll long long
#define u32 unsigned int
#define u64 unsigned long long
#define ON_DEBUGG
#ifdef ON_DEBUGG
#define D_e_Line printf("\n----------\n")
#define D_e(x) cout << (#x) << " : " << x << endl
#define Pause() system("pause")
#define FileOpen() freopen("in.txt", "r", stdin)
#define FileSave() freopen("out.txt", "w", stdout)
#include <ctime>
#define TIME() fprintf(stderr, "\ntime: %.3fms\n", clock() * 1000.0 / CLOCKS_PER_SEC)
#else
#define D_e_Line ;
#define D_e(x) ;
#define Pause() ;
#define FileOpen() ;
#define FileSave() ;
#define TIME() ;
//char buf[1 << 21], *p1 = buf, *p2 = buf;
//#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
#endif
using namespace std;
struct ios{
template<typename ATP>inline ios& operator >> (ATP &x){
x = 0; int f = 1; char ch;
for(ch = getchar(); ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') f = -1;
while(ch >= '0' && ch <= '9') x = x * 10 + (ch ^ '0'), ch = getchar();
x *= f;
return *this;
}
}io;
template<typename ATP>inline ATP Max(ATP a, ATP b){
return a > b ? a : b;
}
template<typename ATP>inline ATP Min(ATP a, ATP b){
return a < b ? a : b;
}
template<typename ATP>inline ATP Abs(ATP a){
return a < 0 ? -a : a;
}
const int N = 1007;
const int M = 2007;
struct Edge{
int nxt, pre;
}e[M];
int head[N], cntEdge = 1;
inline void add(int u, int v){
e[++cntEdge] = (Edge){ head[u], v}, head[u] = cntEdge;
}
int n1, n2;
int vis[N], tim, match[N];
inline bool Hungry(int u){
for(register int i = head[u]; i; i = e[i].nxt){
int v = e[i].pre;
if(vis[v] == tim) continue;
vis[v] = tim;
if(!match[v] || Hungry(match[v])){
match[v] = u;
return true;
}
}
return false;
}
struct Answer{
int x, y;
bool operator < (const Answer &com) const{
return x < com.x;
}
}ans[N << 1];
int main(){
io >> n1 >> n2;
int u, v;
while(~scanf("%d%d", &u, &v) && u != -1){
add(u, v + n1);
}
int sum = 0;
R(i,1,n1){
++tim;
sum += Hungry(i);
}
if(sum == 0){
printf("No Solution!");
return 0;
}
printf("%d\n", sum);
int tot = 0;
R(i,1,n2){
if(match[i + n1]){
// printf("%d %d\n", match[i + n1], i);
ans[++tot] = (Answer){ match[i + n1], i};
}
}
sort(ans + 1, ans + tot + 1);
R(i,1,tot){
printf("%d %d\n", ans[i].x, ans[i].y);
}
return 0;
}
负载平衡问题
最小费用最大流
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#define R(a,b,c) for(register int a = (b); (a) <= (c); ++(a))
#define nR(a,b,c) for(register int a = (b); (a) >= (c); --(a))
#define Fill(a,b) memset(a, b, sizeof(a))
#define Swap(a,b) ((a) ^= (b) ^= (a) ^= (b))
#define ll long long
#define u32 unsigned int
#define u64 unsigned long long
#define ON_DEBUGG
#ifdef ON_DEBUGG
#define D_e_Line printf("\n----------\n")
#define D_e(x) cout << (#x) << " : " << x << endl
#define Pause() system("pause")
#define FileOpen() freopen("in.txt", "r", stdin)
#define FileSave() freopen("out.txt", "w", stdout)
#include <ctime>
#define TIME() fprintf(stderr, "\ntime: %.3fms\n", clock() * 1000.0 / CLOCKS_PER_SEC)
#else
#define D_e_Line ;
#define D_e(x) ;
#define Pause() ;
#define FileOpen() ;
#define FileSave() ;
#define TIME() ;
//char buf[1 << 21], *p1 = buf, *p2 = buf;
//#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
#endif
using namespace std;
struct ios{
template<typename ATP>inline ios& operator >> (ATP &x){
x = 0; int f = 1; char ch;
for(ch = getchar(); ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') f = -1;
while(ch >= '0' && ch <= '9') x = x * 10 + (ch ^ '0'), ch = getchar();
x *= f;
return *this;
}
}io;
template<typename ATP>inline ATP Max(ATP a, ATP b){
return a > b ? a : b;
}
template<typename ATP>inline ATP Min(ATP a, ATP b){
return a < b ? a : b;
}
template<typename ATP>inline ATP Abs(ATP a){
return a < 0 ? -a : a;
}
const int N = 1007;
const int M = 1007;
int S, T;
struct Edge{
int nxt, pre, from, f, w;
}e[M];
int head[N], cntEdge = 1;
inline void add(int u, int v, int f, int w){
e[++cntEdge] = (Edge){ head[u], v, u, f, w}, head[u] = cntEdge;
}
inline void Add(int u, int v, int f, int w){
add(u, v, f, w);
add(v, u, 0, -w);
}
int dis[N], from[N], vis[N];
int q[N];
inline bool SPFA(){
R(i,0,T) dis[i] = 0x3f3f3f3f;
int h = 0, t = 1;
dis[S] = q[S] = 0;
vis[S] = 1;
while(h != t){
int u = q[h++];
vis[u] = 0;
for(register int i = head[u]; i; i = e[i].nxt){
int v = e[i].pre;
if(e[i].f && dis[v] > dis[u] + e[i].w){
from[v] = i;
dis[v] = dis[u] + e[i].w;
if(!vis[v]){
vis[v] = 1;
q[t++] = v;
}
}
}
}
return dis[T] != 0x3f3f3f3f;
}
int ans;
inline void MCMF(){
int i = from[T], flow = 0x3f3f3f3f;
while(i){
flow = Min(flow, e[i].f);
i = from[e[i].from];
}
i = from[T];
while(i){
e[i].f -= flow, e[i ^ 1].f += flow;
ans += flow * e[i].w;
i = from[e[i].from];
}
}
int a[N];
int main(){
int n;
io >> n;
int sum = 0;
S = 0, T = n << 1 | 1;
R(i,1,n){
io >> a[i];
sum += a[i];
}
sum /= n;
R(i,1,n) a[i] -= sum;
R(i,1,n){
if(a[i] > 0)
Add(S, i, a[i], 0);
else
Add(i + n, T, -a[i], 0);
}
R(i,1,n){
if(i != 1){
Add(i, i - 1, 0x3f3f3f3f, 1);
Add(i, i - 1 + n, 0x3f3f3f3f, 1);
}
if(i != n){
Add(i, i + 1, 0x3f3f3f3f, 1);
Add(i, i + 1 + n, 0x3f3f3f3f, 1);
}
}
Add(n, 1, 0x3f3f3f3f, 1);
Add(n, 1 + n, 0x3f3f3f3f, 1);
Add(1, n, 0x3f3f3f3f, 1);
Add(1, n + n, 0x3f3f3f3f, 1);
while(SPFA()){
MCMF();
}
printf("%d", ans);
return 0;
}
运输问题
最小费用最大流,最大费用则取负处理
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#define R(a,b,c) for(register int a = (b); (a) <= (c); ++(a))
#define nR(a,b,c) for(register int a = (b); (a) >= (c); --(a))
#define Fill(a,b) memset(a, b, sizeof(a))
#define Swap(a,b) ((a) ^= (b) ^= (a) ^= (b))
#define ll long long
#define u32 unsigned int
#define u64 unsigned long long
#define ON_DEBUGG
#ifdef ON_DEBUGG
#define D_e_Line printf("\n----------\n")
#define D_e(x) cout << (#x) << " : " << x << endl
#define Pause() system("pause")
#define FileOpen() freopen("in.txt", "r", stdin)
#define FileSave() freopen("out.txt", "w", stdout)
#include <ctime>
#define TIME() fprintf(stderr, "\ntime: %.3fms\n", clock() * 1000.0 / CLOCKS_PER_SEC)
#else
#define D_e_Line ;
#define D_e(x) ;
#define Pause() ;
#define FileOpen() ;
#define FileSave() ;
#define TIME() ;
//char buf[1 << 21], *p1 = buf, *p2 = buf;
//#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
#endif
using namespace std;
struct ios{
template<typename ATP>inline ios& operator >> (ATP &x){
x = 0; int f = 1; char ch;
for(ch = getchar(); ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') f = -1;
while(ch >= '0' && ch <= '9') x = x * 10 + (ch ^ '0'), ch = getchar();
x *= f;
return *this;
}
}io;
template<typename ATP>inline ATP Max(ATP a, ATP b){
return a > b ? a : b;
}
template<typename ATP>inline ATP Min(ATP a, ATP b){
return a < b ? a : b;
}
template<typename ATP>inline ATP Abs(ATP a){
return a < 0 ? -a : a;
}
const int N = 2007;
const int M = 50007;
struct Edge{
int nxt, pre, from, f, w;
}e[M];
int head[N], cntEdge = 1;
inline void add(int u, int v, int f, int w){
e[++cntEdge] = (Edge){head[u], v, u, f, w}, head[u] = cntEdge;
}
inline void Add(int u, int v, int f, int w){
add(u, v, f, w);
add(v, u, 0, -w);
}
int n, m, S, T;
int dis[N], vis[N], q[N], from[N];
inline bool SPFA(){
R(i,S,T) dis[i] = 0x3f3f3f3f;
int top = 1;
dis[S] = 0, q[top] = S, vis[S] = 1;
while(top){
int u = q[top--];
vis[u] = 0;
for(register int i = head[u]; i; i = e[i].nxt){
int v = e[i].pre;
if(e[i].f && dis[v] > dis[u] + e[i].w){
from[v] = i;
dis[v] = dis[u] + e[i].w;
if(!vis[v]){
vis[v] = 1;
q[++top] = v;
}
}
}
}
return dis[T] != 0x3f3f3f3f;
}
int ans;
inline void MCMF(){
int i = from[T], flow = 0x3f3f3f3f;
while(i){
flow = Min(flow, e[i].f);
i = from[e[i].from];
}
i = from[T];
while(i){
e[i].f -= flow, e[i ^ 1].f += flow;
ans += flow * e[i].w;
i = from[e[i].from];
}
}
int cost[N][N];
int tmp1[N], tmp2[N];
int main(){
//FileOpen();
io >> n >> m;
T = n + m + 1;
R(i,1,n){
int x;
io >> x;
tmp1[i] = x;
Add(S, i, x, 0);
}
R(i,1,m){
int x;
io >> x;
tmp2[i] = x;
Add(i + n, T, x, 0);
}
R(i,1,n){
R(j,1,m){
int x;
io >> x;
Add(i, j + n, 0x3f3f3f3f, x);
cost[i][j] = x;
}
}
while(SPFA()) MCMF();
printf("%d\n", ans);
ans = 0;
cntEdge = 1;
Fill(head, 0);
R(i,1,n){
int x = tmp1[i];
Add(S, i, x, 0);
}
R(i,1,m){
int x = tmp2[i];
Add(i + n, T, x, 0);
}
R(i,1,n){
R(j,1,m){
Add(i, j + n, 0x3f3f3f3f, -cost[i][j]);
}
}
while(SPFA()) MCMF();
printf("%d", -ans);
return 0;
}
分配问题
二分图最佳匹配
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#define R(a,b,c) for(register int a = (b); (a) <= (c); ++(a))
#define nR(a,b,c) for(register int a = (b); (a) >= (c); --(a))
#define Fill(a,b) memset(a, b, sizeof(a))
#define Swap(a,b) ((a) ^= (b) ^= (a) ^= (b))
#define ll long long
#define u32 unsigned int
#define u64 unsigned long long
#define ON_DEBUGG
#ifdef ON_DEBUGG
#define D_e_Line printf("\n----------\n")
#define D_e(x) cout << (#x) << " : " << x << endl
#define Pause() system("pause")
#define FileOpen() freopen("in.txt", "r", stdin)
#define FileSave() freopen("out.txt", "w", stdout)
#include <ctime>
#define TIME() fprintf(stderr, "\ntime: %.3fms\n", clock() * 1000.0 / CLOCKS_PER_SEC)
#else
#define D_e_Line ;
#define D_e(x) ;
#define Pause() ;
#define FileOpen() ;
#define FileSave() ;
#define TIME() ;
//char buf[1 << 21], *p1 = buf, *p2 = buf;
//#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
#endif
using namespace std;
struct ios{
template<typename ATP>inline ios& operator >> (ATP &x){
x = 0; int f = 1; char ch;
for(ch = getchar(); ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') f = -1;
while(ch >= '0' && ch <= '9') x = x * 10 + (ch ^ '0'), ch = getchar();
x *= f;
return *this;
}
}io;
template<typename ATP>inline ATP Max(ATP a, ATP b){
return a > b ? a : b;
}
template<typename ATP>inline ATP Min(ATP a, ATP b){
return a < b ? a : b;
}
template<typename ATP>inline ATP Abs(ATP a){
return a < 0 ? -a : a;
}
const int N = 50007;
const int M = 50007;
int n, S, T;
struct Edge{
int nxt, pre, from, w, f;
}e[M];
int head[N], cntEdge = 1;
inline void add(int u, int v, int f, int w){
e[++cntEdge] = (Edge){ head[u], v, u, w, f}, head[u] = cntEdge;
}
inline void Add(int u, int v, int f, int w){
add(u, v, f, w);
add(v, u, 0, -w);
}
int dis[N], q[N], vis[N], from[N];
inline bool SPFA(){
R(i,S,T) dis[i] = 0x3f3f3f3f;
int h = 0, t = 1;
dis[S] = 0, q[h] = S, vis[S] = 1;
while(h != t){
int u = q[h++];
vis[u] = 0;
for(register int i = head[u]; i; i = e[i].nxt){
int v = e[i].pre;
if(e[i].f && dis[v] > dis[u] + e[i].w){
from[v] = i;
dis[v] = dis[u] + e[i].w;
if(!vis[v]){
vis[v] = 1;
q[t++] = v;
}
}
}
}
return dis[T] != 0x3f3f3f3f;
}
int ans;
inline void MCMF(){
int i = from[T], flow = 0x3f3f3f3f;
while(i){
flow = Min(flow, e[i].f);
i = from[e[i].from];
}
i = from[T];
while(i){
ans += e[i].w * flow;
e[i].f -= flow, e[i ^ 1].f += flow;
i = from[e[i].from];
}
}
int cost[107][107];
int main(){
//FileOpen();
io >> n;
T = n << 1 | 1;
R(i,1,n){
Add(S, i, 1, 0);
}
R(i,1,n){
Add(i + n, T, 1, 0);
}
R(i,1,n){
R(j,1,n){
int x;
io >> x;
cost[i][j] = x;
Add(i, j + n, 1, x);
}
}
while(SPFA()) MCMF();
printf("%d\n", ans);
ans = 0;
cntEdge = 1;
Fill(head, 0);
R(i,1,n){
Add(S, i, 1, 0);
}
R(i,1,n){
Add(i + n, T, 1, 0);
}
R(i,1,n){
R(j,1,n){
Add(i, j + n, 1, -cost[i][j]);
}
}
while(SPFA()) MCMF();
printf("%d", -ans);
return 0;
}
最小路径覆盖问题
DAG最小路径覆盖
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#define R(a,b,c) for(register int a = (b); (a) <= (c); ++(a))
#define nR(a,b,c) for(register int a = (b); (a) >= (c); --(a))
#define Fill(a,b) memset(a, b, sizeof(a))
#define Swap(a,b) ((a) ^= (b) ^= (a) ^= (b))
#define ll long long
#define u32 unsigned int
#define u64 unsigned long long
#define ON_DEBUGG
#ifdef ON_DEBUGG
#define D_e_Line printf("\n----------\n")
#define D_e(x) cout << (#x) << " : " << x << endl
#define Pause() system("pause")
#define FileOpen() freopen("in.txt", "r", stdin)
#define FileSave() freopen("out.txt", "w", stdout)
#include <ctime>
#define TIME() fprintf(stderr, "\ntime: %.3fms\n", clock() * 1000.0 / CLOCKS_PER_SEC)
#else
#define D_e_Line ;
#define D_e(x) ;
#define Pause() ;
#define FileOpen() ;
#define FileSave() ;
#define TIME() ;
//char buf[1 << 21], *p1 = buf, *p2 = buf;
//#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
#endif
using namespace std;
struct ios{
template<typename ATP>inline ios& operator >> (ATP &x){
x = 0; int f = 1; char ch;
for(ch = getchar(); ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') f = -1;
while(ch >= '0' && ch <= '9') x = x * 10 + (ch ^ '0'), ch = getchar();
x *= f;
return *this;
}
}io;
template<typename ATP>inline ATP Max(ATP a, ATP b){
return a > b ? a : b;
}
template<typename ATP>inline ATP Min(ATP a, ATP b){
return a < b ? a : b;
}
template<typename ATP>inline ATP Abs(ATP a){
return a < 0 ? -a : a;
}
const int N = 50007;
const int M = 50007;
int n, S, T;
struct Edge{
int nxt, pre, f;
}e[M];
int head[N], cntEdge = 1;
inline void add(int u, int v, int f){
e[++cntEdge] = (Edge){ head[u], v, f}, head[u] = cntEdge;
}
inline void Add(int u, int v, int f){
add(u, v, f);
add(v, u, 0);
}
int vis[M];
int cur[N], q[N], d[N];
inline bool BFS(){
int h = 0, t = 1;
R(i,S,T) d[i] = -1;
d[S] = 0, q[0] = S;
while(h != t){
int u = q[h++];
if(h > 10000) h = 0;
for(register int i = head[u]; i; i = e[i].nxt){
int v = e[i].pre;
if(e[i].f && d[v] == -1){
d[v] = d[u] + 1;
q[t++] = e[i].pre;
if(t > 10000) t = 0;
}
}
}
return d[T] != -1;
}
int nxt[N];
inline int DFS(int u, int f){
if(u == T) return f;
int flow, used = 0;
for(register int i = cur[u]; i; i = e[i].nxt){
cur[u] = i;
int v = e[i].pre;
if(d[v] == d[u] + 1){
flow = DFS(v, Min(f - used, e[i].f));
if(flow){
nxt[u] = v;
if(v > n) vis[v - n] = 1;
}
e[i].f -= flow, e[i ^ 1].f += flow;
used += flow;
if(used == f) return f;
}
}
if(!used) d[u] = -1;
return used;
}
inline int Dinic(){
int sum = 0;
while(BFS()){
R(i,S,T) cur[i] = head[i];
sum += DFS(S, 0x7fffffff);
}
return sum;
}
int main(){
//FileOpen();
int m;
io >> n >> m;
T = n << 1 | 1;
R(i,1,n) Add(S, i, 1);
R(i,1,n) Add(i + n, T, 1);
R(i,1,m){
int u, v;
io >> u >> v;
Add(u, v + n, 0x3f3f3f3f);
}
int ans = n - Dinic();
R(i,1,n){
if(vis[i]) continue;
printf("%d ", i);
register int j;
for(j = i; nxt[j]; j = nxt[j] - n){
printf("%d ", nxt[j] - n);
}
putchar('\n');
}
printf("%d",ans);
return 0;
}
太空飞行计划问题
最大权闭合图
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#define R(a,b,c) for(register int a = (b); (a) <= (c); ++(a))
#define nR(a,b,c) for(register int a = (b); (a) >= (c); --(a))
#define Fill(a,b) memset(a, b, sizeof(a))
#define Swap(a,b) ((a) ^= (b) ^= (a) ^= (b))
#define ll long long
#define u32 unsigned int
#define u64 unsigned long long
#define ON_DEBUGG
#ifdef ON_DEBUGG
#define D_e_Line printf("\n----------\n")
#define D_e(x) cout << (#x) << " : " << x << endl
#define Pause() system("pause")
#define FileOpen() freopen("in.txt", "r", stdin)
#define FileSave() freopen("out.txt", "w", stdout)
#include <ctime>
#define TIME() fprintf(stderr, "\ntime: %.3fms\n", clock() * 1000.0 / CLOCKS_PER_SEC)
#else
#define D_e_Line ;
#define D_e(x) ;
#define Pause() ;
#define FileOpen() ;
#define FileSave() ;
#define TIME() ;
//char buf[1 << 21], *p1 = buf, *p2 = buf;
//#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
#endif
using namespace std;
struct ios{
template<typename ATP>inline ios& operator >> (ATP &x){
x = 0; int f = 1; char ch;
for(ch = getchar(); ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') f = -1;
while(ch >= '0' && ch <= '9') x = x * 10 + (ch ^ '0'), ch = getchar();
x *= f;
return *this;
}
}io;
template<typename ATP>inline ATP Max(ATP a, ATP b){
return a > b ? a : b;
}
template<typename ATP>inline ATP Min(ATP a, ATP b){
return a < b ? a : b;
}
template<typename ATP>inline ATP Abs(ATP a){
return a < 0 ? -a : a;
}
const int N = 20007;
const int M = 20007;
struct Edge{
int nxt, pre, f;
}e[M];
int head[N], cntEdge = 1;
inline void add(int u, int v, int f){
e[++cntEdge] = (Edge){ head[u], v, f}, head[u] = cntEdge;
}
inline void Add(int u, int v, int f){
add(u, v, f);
add(v, u, 0);
}
int n, m, S, T;
int cur[N], d[N], q[N];
inline bool BFS(){
R(i,S,T) d[i] = -1;
int h = 0, t = 1;
d[S] = 0, q[h] = S;
while(h != t){
int u = q[h++];
if(h > 10000) h = 0;
for(register int i = head[u]; i; i = e[i].nxt){
int v = e[i].pre;
if(e[i].f && d[v] == -1){
d[v] = d[u] + 1;
q[t++] = v;
if(t > 10000) t = 0;
}
}
}
return d[T] != -1;
}
inline int DFS(int u, int f){
if(u == T) return f;
int flow, used = 0;
for(register int i = cur[u]; i; i = e[i].nxt){
cur[u] = i;
int v = e[i].pre;
if(d[v] == d[u] + 1){
flow = DFS(v, Min(e[i].f, f - used));
e[i].f -= flow, e[i ^ 1].f += flow;
used += flow;
if(used == f) return f;
}
}
if(!used) d[u] = -1;
return used;
}
inline int Dinic(){
int sum = 0;
while(BFS()){
R(i,S,T) cur[i] = head[i];
sum += DFS(S, 0x7fffffff);
}
return sum;
}
inline bool read(int &x){
x = 0; int f = 1; char ch;
for(ch = getchar(); ch < '0' || ch > '9'; ch = getchar()){
if(ch == '-')
f = -1;
else if(ch == '\n')
return false;
}
while(ch >= '0' && ch <= '9') x = x * 10 + (ch ^ '0'), ch = getchar();
x *= f;
if(ch == '\n' || ch == '\r') return false;
return true;
}
int main(){
//FileOpen();
io >> m >> n;
T = n + m + 1;
int ans = 0;
// S -> m -> n -> T
R(i,1,m){
int val;
io >> val;
Add(S, i, val);
ans += val;
int x;
while(read(x)) Add(i, x + m, 0x3f3f3f3f);
Add(i, x + m, 0x3f3f3f3f);
}
R(i,1,n){
int val;
io >> val;
Add(i + m, T, val);
}
ans -= Dinic();
R(i,1,m - 1){
if(~d[i]){
printf("%d ", i);
}
}
if(~d[m]) printf("%d", m);
putchar('\n');
R(i,1,n - 1){
if(~d[i + m]){
printf("%d ", i);
}
}
if(~d[n + m]) printf("%d", n);
putchar('\n');
printf("%d", ans);
return 0;
}
/*
4 5
10 2 3
12 1
13 4
10 4 5
6 7 8 9 9
*/
圆桌问题
二分图多重匹配
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#define R(a,b,c) for(register int a = (b); (a) <= (c); ++(a))
#define nR(a,b,c) for(register int a = (b); (a) >= (c); --(a))
#define Fill(a,b) memset(a, b, sizeof(a))
#define Swap(a,b) ((a) ^= (b) ^= (a) ^= (b))
#define ll long long
#define u32 unsigned int
#define u64 unsigned long long
#define ON_DEBUGG
#ifdef ON_DEBUGG
#define D_e_Line printf("\n----------\n")
#define D_e(x) cout << (#x) << " : " << x << endl
#define Pause() system("pause")
#define FileOpen() freopen("in.txt", "r", stdin)
#define FileSave() freopen("out.txt", "w", stdout)
#include <ctime>
#define TIME() fprintf(stderr, "\ntime: %.3fms\n", clock() * 1000.0 / CLOCKS_PER_SEC)
#else
#define D_e_Line ;
#define D_e(x) ;
#define Pause() ;
#define FileOpen() ;
#define FileSave() ;
#define TIME() ;
//char buf[1 << 21], *p1 = buf, *p2 = buf;
//#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
#endif
using namespace std;
struct ios{
template<typename ATP>inline ios& operator >> (ATP &x){
x = 0; int f = 1; char ch;
for(ch = getchar(); ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') f = -1;
while(ch >= '0' && ch <= '9') x = x * 10 + (ch ^ '0'), ch = getchar();
x *= f;
return *this;
}
}io;
template<typename ATP>inline ATP Max(ATP a, ATP b){
return a > b ? a : b;
}
template<typename ATP>inline ATP Min(ATP a, ATP b){
return a < b ? a : b;
}
template<typename ATP>inline ATP Abs(ATP a){
return a < 0 ? -a : a;
}
const int N = 507;
const int M = 100007;
struct Edge{
int nxt, pre, f;
}e[M];
int head[N], cntEdge = 1;
inline void add(int u, int v, int f){
e[++cntEdge] = (Edge){ head[u], v, f}, head[u] = cntEdge;
}
inline void Add(int u, int v, int f){
add(u, v, f);
add(v, u, 0);
}
int n, m, S, T;
int cur[N], q[N], d[N];
inline bool BFS(){
R(i,S,T) d[i] = -1;
int t = 1, h = 0;
q[h] = S, d[S] = 0;
while(h != t){
int u = q[h++];
if(h > N - 5) h = 0;
for(register int i = head[u]; i; i = e[i].nxt){
int v = e[i].pre;
if(e[i].f && d[v] == -1){
d[v] = d[u] + 1;
q[t++] = v;
if(t > N - 5) t = 0;
}
}
}
return d[T] != -1;
}
inline int DFS(int u, int f){
if(u == T) return f;
int flow, used = 0;
for(register int i = cur[u]; i; i = e[i].nxt){
cur[u] = i;
int v = e[i].pre;
if(d[v] == d[u] + 1){
flow = DFS(v, Min(f - used, e[i].f));
e[i].f -= flow, e[i ^ 1].f += flow;
used += flow;
if(used == f) return f;
}
}
if(!used) d[u] = -1;
return used;
}
int ans;
inline void Dinic(){
while(BFS()){
R(i,S,T) cur[i] = head[i];
ans += DFS(S, 0x7fffffff);
}
}
int main(){
//FileOpen();
//FileSave();
io >> m >> n;
T = n + m + 1;
int sum = 0;
R(i,1,m){
int x;
io >> x;
sum += x;
Add(S, i, x);
}
R(i,1,n){
int x;
io >> x;
Add(i + m, T, x);
}
R(i,1,m){
R(j,1,n){
Add(i,j + m, 1);
}
}
Dinic();
if(ans != sum){
printf("0");
return 0;
}
printf("1\n");
R(u,1,m){
for(register int i = head[u]; i; i = e[i].nxt){
int v = e[i].pre;
if(!e[i].f && v != S){
printf("%d ", v - m);
}
}
putchar('\n');
}
return 0;
}
/*
S -> m -> n -> T
*/
试题库问题
二分图多重匹配
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#define R(a,b,c) for(register int a = (b); (a) <= (c); ++(a))
#define nR(a,b,c) for(register int a = (b); (a) >= (c); --(a))
#define Fill(a,b) memset(a, b, sizeof(a))
#define Swap(a,b) ((a) ^= (b) ^= (a) ^= (b))
#define ll long long
#define u32 unsigned int
#define u64 unsigned long long
#define ON_DEBUGG
#ifdef ON_DEBUGG
#define D_e_Line printf("\n----------\n")
#define D_e(x) cout << (#x) << " : " << x << endl
#define Pause() system("pause")
#define FileOpen() freopen("in.txt", "r", stdin)
#define FileSave() freopen("out.txt", "w", stdout)
#include <ctime>
#define TIME() fprintf(stderr, "\ntime: %.3fms\n", clock() * 1000.0 / CLOCKS_PER_SEC)
#else
#define D_e_Line ;
#define D_e(x) ;
#define Pause() ;
#define FileOpen() ;
#define FileSave() ;
#define TIME() ;
//char buf[1 << 21], *p1 = buf, *p2 = buf;
//#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
#endif
using namespace std;
struct ios{
template<typename ATP>inline ios& operator >> (ATP &x){
x = 0; int f = 1; char ch;
for(ch = getchar(); ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') f = -1;
while(ch >= '0' && ch <= '9') x = x * 10 + (ch ^ '0'), ch = getchar();
x *= f;
return *this;
}
}io;
template<typename ATP>inline ATP Max(ATP a, ATP b){
return a > b ? a : b;
}
template<typename ATP>inline ATP Min(ATP a, ATP b){
return a < b ? a : b;
}
template<typename ATP>inline ATP Abs(ATP a){
return a < 0 ? -a : a;
}
const int N = 1007;
const int M = 1000007;
struct Edge{
int nxt, pre, f;
}e[M];
int head[N], cntEdge = 1;
inline void add(int u, int v, int f){
e[++cntEdge] = (Edge){ head[u], v, f}, head[u] = cntEdge;
}
inline void Add(int u, int v, int f){
add(u, v, f);
add(v, u, 0);
}
int n, m, S, T;
int cur[N], q[N], d[N];
inline bool BFS(){
R(i,S,T) d[i] = -1;
int t = 1, h = 0;
d[S] = 0, q[0] = S;
while(t != h){
int u = q[h++];
if(h > N - 5) h = 0;
for(register int i = head[u]; i; i = e[i].nxt){
int v = e[i].pre;
if(e[i].f && d[v] == -1){
d[v] = d[u] + 1;
q[t++] = v;
if(t > N - 5) t = 0;
}
}
}
return d[T] != -1;
}
inline int DFS(int u, int f){
if(u == T) return f;
int flow, used = 0;
for(register int i= head[u]; i; i = e[i].nxt){
int v = e[i].pre;
if(d[v] == d[u] + 1){
flow = DFS(v, Min(f - used, e[i].f));
e[i].f -= flow, e[i ^ 1].f += flow;
used += flow;
if(used == f) return f;
}
}
if(!used) d[u] = -1;
return used;
}
int maxFlow;
inline void Dinic(){
while(BFS()){
R(i,S,T) cur[i] = head[i];
maxFlow += DFS(S, 0x7fffffff);
}
}
int main(){
io >> m >> n; // m := k
T = n + m + 1;
int sum = 0;
R(i,1,m){
int x;
io >> x;
sum += x;
Add(S, i, x);
}
R(i,1,n){
int p;
io >> p;
while(p--){
int x;
io >> x;
Add(x, i + m, 1);
}
}
R(i,1,n){
Add(i + m, T, 1);
}
Dinic();
if(maxFlow != sum){
printf("No Solution!");
return 0;
}
R(u,1,m){
printf("%d: ", u);
for(register int i = head[u]; i; i = e[i].nxt){
int v = e[i].pre;
if(!e[i].f && v != S){
printf("%d ", v - m);
}
}
putchar('\n');
}
return 0;
}
/*
S -> m -> n -> T
*/
餐巾计划问题
线性规划网络优化
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#define R(a,b,c) for(register int a = (b); (a) <= (c); ++(a))
#define nR(a,b,c) for(register int a = (b); (a) >= (c); --(a))
#define Fill(a,b) memset(a, b, sizeof(a))
#define Swap(a,b) ((a) ^= (b) ^= (a) ^= (b))
#define ll long long
#define u32 unsigned int
#define u64 unsigned long long
#define ON_DEBUGG
#ifdef ON_DEBUGG
#define D_e_Line printf("\n----------\n")
#define D_e(x) cout << (#x) << " : " << x << endl
#define Pause() system("pause")
#define FileOpen() freopen("in.txt", "r", stdin)
#define FileSave() freopen("out.txt", "w", stdout)
#include <ctime>
#define TIME() fprintf(stderr, "\ntime: %.3fms\n", clock() * 1000.0 / CLOCKS_PER_SEC)
#else
#define D_e_Line ;
#define D_e(x) ;
#define Pause() ;
#define FileOpen() ;
#define FileSave() ;
#define TIME() ;
//char buf[1 << 21], *p1 = buf, *p2 = buf;
//#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
#endif
using namespace std;
struct ios{
template<typename ATP>inline ios& operator >> (ATP &x){
x = 0; int f = 1; char ch;
for(ch = getchar(); ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') f = -1;
while(ch >= '0' && ch <= '9') x = x * 10 + (ch ^ '0'), ch = getchar();
x *= f;
return *this;
}
}io;
template<typename ATP>inline ATP Max(ATP a, ATP b){
return a > b ? a : b;
}
template<typename ATP>inline ATP Min(ATP a, ATP b){
return a < b ? a : b;
}
template<typename ATP>inline ATP Abs(ATP a){
return a < 0 ? -a : a;
}
const int N = 4007;
const int M = 1000007;
struct Edge{
int nxt, pre, from, f, w;
}e[M];
int head[N], cntEdge = 1;
inline void add(int u, int v, int f, int w){
e[++cntEdge] = (Edge){ head[u], v, u, f, w}, head[u] = cntEdge;
}
inline void Add(int u, int v, int f, int w){
add(u, v, f, w);
add(v, u, 0, -w);
}
int n, S, T;
int q[N], from[N], vis[N];
long long dis[N];
inline bool SPFA(){
R(i,S,T) dis[i] = 0x3f3f3f3f;
int top = 1;
dis[S] = 0, q[1] = S;
while(top){
int u = q[top--];
vis[u] = false;
for(register int i = head[u]; i; i = e[i].nxt){
int v = e[i].pre;
if(e[i].f && dis[v] > dis[u] + (long long)e[i].w){
from[v] = i;
dis[v] = dis[u] + (long long)e[i].w;
if(!vis[v]){
vis[v] = true;
q[++top] = v;
}
}
}
}
return dis[T] != 0x3f3f3f3f;
}
long long ans;
inline void MCMF(){
int i = from[T], flow = 0x3f3f3f3f;
while(i){
flow = Min(flow, e[i].f);
i = from[e[i].from];
}
i = from[T];
while(i){
ans += (long long)e[i].w * flow;
e[i].f -= flow, e[i ^ 1].f += flow;
i = from[e[i].from];
}
}
int main(){
//FileOpen();
io >> n;
T = n << 1 | 1;
R(i,1,n){
int x;
io >> x;
Add(S, i + n, x, 0);
Add(i, T, x, 0);
}
int price, fastDays, fastCost, slowDays, slowCost;
io >> price >> fastDays >> fastCost >> slowDays >> slowCost;
R(i,1,n){
if(i + 1 <= n) Add(i + n, i + 1 + n, 0x3f3f3f3f, 0);
if(i + slowDays <= n) Add(i + n, i + slowDays, 0x3f3f3f3f, slowCost);
if(i + fastDays <= n) Add(i + n, i + fastDays, 0x3f3f3f3f, fastCost);
Add(S, i, 0x3f3f3f3f, price);
}
while(SPFA()) MCMF();
printf("%lld", ans);
return 0;
}
/*
S -> i_1 -> i_2 -> T
*/
航空路线问题
航空路线问题
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#define R(a,b,c) for(register int a = (b); (a) <= (c); ++(a))
#define nR(a,b,c) for(register int a = (b); (a) >= (c); --(a))
#define Fill(a,b) memset(a, b, sizeof(a))
#define Swap(a,b) ((a) ^= (b) ^= (a) ^= (b))
#define ll long long
#define u32 unsigned int
#define u64 unsigned long long
#define ON_DEBUGG
#ifdef ON_DEBUGG
#define D_e_Line printf("\n----------\n")
#define D_e(x) cout << (#x) << " : " << x << endl
#define Pause() system("pause")
#define FileOpen() freopen("in.txt", "r", stdin)
#define FileSave() freopen("out.txt", "w", stdout)
#include <ctime>
#define TIME() fprintf(stderr, "\ntime: %.3fms\n", clock() * 1000.0 / CLOCKS_PER_SEC)
#else
#define D_e_Line ;
#define D_e(x) ;
#define Pause() ;
#define FileOpen() ;
#define FileSave() ;
#define TIME() ;
//char buf[1 << 21], *p1 = buf, *p2 = buf;
//#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
#endif
using namespace std;
struct ios{
template<typename ATP>inline ios& operator >> (ATP &x){
x = 0; int f = 1; char ch;
for(ch = getchar(); ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') f = -1;
while(ch >= '0' && ch <= '9') x = x * 10 + (ch ^ '0'), ch = getchar();
x *= f;
return *this;
}
}io;
template<typename ATP>inline ATP Max(ATP a, ATP b){
return a > b ? a : b;
}
template<typename ATP>inline ATP Min(ATP a, ATP b){
return a < b ? a : b;
}
template<typename ATP>inline ATP Abs(ATP a){
return a < 0 ? -a : a;
}
const int N = 1007;
const int M = 1000007;
struct Edge{
int nxt, pre, f, w;
}e[M];
int head[N], cntEdge = 1;
inline void add(int u, int v, int f, int w){
e[++cntEdge] = (Edge){ head[u], v, f, w}, head[u] = cntEdge;
}
inline void Add(int u, int v, int f, int w){
add(u, v, f, w);
add(v, u, 0, -w);
}
int n, S, T;
int dis[N], vis[N], from[N], q[N];
inline bool SPFA(){
R(i,S,T) dis[i] = 0x3f3f3f3f;
int top = 1;
dis[S] = 0, q[top] = S;
while(top){
int u = q[top--];
vis[u] = false;
for(register int i = head[u]; i; i = e[i].nxt){
int v = e[i].pre;
if(e[i].f && dis[v] > dis[u] + e[i].w){
dis[v] = dis[u] + e[i].w;
from[v] = i;
if(!vis[v]){
vis[v] = true;
q[++top] = v;
}
}
}
}
return dis[T] != 0x3f3f3f3f;
}
int ans, maxFlow;
inline void MCMF(){
int i = from[T], flow = 0x3f3f3f3f;
while(i){
flow = Min(flow, e[i].f);
i = from[e[i ^ 1].pre];
}
i = from[T];
while(i){
ans += e[i].w * flow;
e[i].f -= flow, e[i ^ 1].f += flow;
i = from[e[i ^ 1].pre];
}
maxFlow += flow;
}
namespace TRIE{
struct Trie{
int ch[53], val;
}t[N];
int trieIndex;
inline void Add(char *str, int val){
int rt = 0, len = strlen(str + 1);
R(i,1,len){
int k = str[i] - 'A';
if(t[rt].ch[k] == 0) t[rt].ch[k] = ++trieIndex;
rt = t[rt].ch[k];
}
t[rt].val = val;
}
inline int Find(char *str){
int rt = 0, len = strlen(str + 1);
R(i,1,len){
int k = str[i] - 'A';
rt = t[rt].ch[k];
}
return t[rt].val;
}
}
char name1[17], name2[17];
char str[N][17];
int main(){
//FileOpen();
int m;
io >> n >> m;
S = 1, T = n << 1;
R(i,1,n){
scanf("%s", str[i] + 1);
TRIE::Add(str[i], i);
if(i != 1 && i != n)
Add(i, i + n, 1, -1);
else
Add(i, i + n, 2, -1);
}
R(i,1,m){
scanf("%s%s", name1 + 1, name2 + 1);
int u = TRIE::Find(name1), v = TRIE::Find(name2);
if(u > v) Swap(u, v);
if(u != 1 || v != n)
Add(u + n, v, 1, 0);
else
Add(u + n, v, 2, 0);
}
while(SPFA()) MCMF();
if(maxFlow != 2){
printf("No Solution!");
return 0;
}
ans = -ans - 2;
printf("%d\n", ans);
vis[1] = vis[0] = 1;
printf("%s\n", str[1] + 1);
for(register int i = head[S + n]; i; i = e[i].nxt){
int u = e[i].pre;
if(!e[i].f && !vis[u]){
while(!vis[u]){
vis[u] = 1;
printf("%s\n", str[u] + 1);
for(register int j = head[u + n]; j; j = e[j].nxt){
int v = e[j].pre;
if(!e[j].f && !vis[v]){
u = v;
break;
}
}
}
break;
}
}
for(register int i = head[n]; i; i = e[i].nxt){
int u = e[i].pre;
if(!e[i ^ 1].f && !vis[u - n]){
u = u - n;
while(!vis[u]){
vis[u] = 1;
printf("%s\n", str[u] + 1);
for(register int j = head[u]; j; j = e[j].nxt){
int v = e[j].pre;
if(!e[j ^ 1].f && !vis[v - n]){
u = v - n;
break;
}
}
}
break;
}
}
printf("%s\n", str[1] + 1);
return 0;
}
没看的了,咕了