令人崩潰的五道題
首先是網路流24題中的前五題
標準的二分圖匹配,這裡採用時間複雜度最優秀o(sqrt(e)v)的網路流做法
建立源點s匯點t分別連線至二分圖的兩個部分
所有邊權設定為1
跑最大流即可
#include #include#include
#include
#include
#include
#include
using
namespace
std;
#define n 105
#define next nico
int head[n],to[n*n*2],next[n*n*2],dis[n*n*2],tot=1,d[n],s=0
,t,n,m;
void add(int x,int y, int
z)int
bfs()}}
return
d[t];
}int dfs(int x,int
v) }
return
ans;
}int
main()
for(int i = 1; i <= m; i ++)
for(int i = m +1; i <= n ; i++)
s=n+2;t=n+1
;
int ans = 0
;
while
(bfs())
if(ans!=0
) }}
}else puts("
no solution!");
}
最大邊權子圖的模板題問題
將模型轉化成二分圖,對於正權點連線源點,負權點連線匯點
跑最大流即可
答案是正權點數總和減去最大流
選取的點是阻塞流到達的點
#include #include#include
#include
#include
#include
using
namespace
std;
#define n 1000
#define next nico
intm, n;
const
int inf = 0x0f7f7f7f
;int head[n], next[n * n], to[n], tot = 1
, val[n];
intsum;
void add(int x, int y, int
z)int
d[n];
int bfs(int s, int
t) }
return
d[t];
}int dfs(int x, int v, int
t)
return
ans;
}int
main()
else
if (a == 0
) p++;
else
while
(a)
p++;}}
for (int i = 1; i <= n; i++)
int ans = 0
;
while (bfs(n + m + 1, n + m + 2
))
for (int j = head[n + m + 1]; j; j =next[j])
if (d[to[j]] != 0
)
puts(
"");
for (int j = head[n + m + 2]; j; j =next[j])
if (d[to[j]]!= 0
)
puts(
"");
printf(
"%d\n
", sum -ans);
}
轉化成二分圖匹配問題即可
#include #include#include
#include
#include
#include
using
namespace
std;
#define n 400
#define next nico
int head[n],to[30005],next[30005],tot=1,dis[30005
],n,m,d[n],s,t;
bool
vis[n];
void add(int x,int y,int
z)int
bfs()
}return
d[t];
}int dfs(int x,int
v)
return
ans;
}void printans(int
x) }
}int
main()
s = 2*n+1;t = s+1
;
for(int i = 1; i <= n ; i ++)
int ans = 0
;
while
(bfs())
for(int i = 1; i <= n; i ++)
if(!vis[i])
printf("%d
",n-ans);
}
可以貪心做
我採取將其轉化成最小路徑覆蓋問題解決
#include #include#include
#include
#include
#include
#include
#include
using
namespace
std;
#define next nico
#define n 5000
#define m 2000
int head[n],d[n],next[n*n],to[n*n],val[n*n],tot=1
;int ans[100
][n],tot1;
intvis[n];
void add(int a , int b ,int
c)int
s,t;
void getans(intx)}
intbfs()
}return
d[t];
}int dfs(int x,int
v)
return
ans;
}int
main()
}while
(bfs())
if(i-sum>n)break
; tot1 = 0
; memset(vis,
0,sizeof
(vis));
for(int j = 1; j <= i; j ++)
if(!vis[j])
}printf(
"%d\n
",i-1
);
for(int i = 1 ; i<= tot1; i ++)
puts(
"");
}}
與普通的二分圖匹配不同,連線源點邊權賦值為容納人數
#include #include#include
#include
#include
#include
#include
using
namespace
std;
#define n 1000
#define next nico
int head[n],next[n*n],to[n*n],v[n*n],tot=1
,s,t;
int* val =v;
intd[n];
void add(int x,int y,int
z)int
bfs()
}return
d[t];
}int dfs(int x,int
v)
return
ans ;
}int
main()
for(int i = 1; i <= n ; i ++)
for(int i = 1; i <= n; i ++)
for(int j = 1; j <= m; j ++)
int ans = 0
;
while
(bfs())
if(ans ==sum)
}puts(
"");}}
else
}
網路流 24 題
1 搭配飛行員 題意 n個飛行員,其中有m名飛行員是正駕駛員。飛機每架有兩個駕駛員,需乙個正駕駛員和乙個副駕駛員。由於種種原因,例如相互配合的問題,有些駕駛員不能在同一架飛機上飛行,問如何搭配駕駛員才能使出航的飛機最多。思路 裸二分圖匹配 最大流 題 版本一 網路流做法 引入源點s 0以及匯點t n...
網路流24題
學會網路流演算法後,我們要做的就是把問題轉化成網路流問題。求二分圖最大匹配。網路流建模要找到問題的關鍵特點,用連邊,流量 以及費用 把原問題轉化成網路流問題,包括最大流,最小割,費用流。二分圖最大匹配的特點是每個點最多屬於一條匹配邊。這相當於是說,每個點只能流過一次。要求的是最大匹配,可以得出建模為...
網路流24題
經典問題,做了一部分 太水的就不記錄了 最大流是對於一種完整的匹配的處理,一條路乙個貢獻。要求匹配盡可能多。費用流是對於乙個路徑的最值的處理,每條邊自己的費用。再匹配最多前提下,匹配的費用達到最值。難點就是對於條件狀態的設計 網路流24題 餐巾計畫問題 費用流建模 考慮每天一定有ri條髒毛巾,所以髒...