由 于 每 个 人 只 能 匹 配 一 种 饮 料 由于每个人只能匹配一种饮料 由于每个人只能匹配一种饮料
所 以 可 以 看 成 匹 配 问 题 , 并 且 匹 配 有 权 值 , 所 以 用 最 大 费 用 最 大 流 所以可以看成匹配问题,并且匹配有权值,所以用最大费用最大流 所以可以看成匹配问题,并且匹配有权值,所以用最大费用最大流
Ⅰ . 源 点 向 6 种 字 符 串 连 边 , 流 量 无 限 大 , 权 值 为 0 Ⅰ.源点向6种字符串连边,流量无限大,权值为0 Ⅰ.源点向6种字符串连边,流量无限大,权值为0
Ⅱ . 每 种 字 符 串 向 对 应 的 第 i 喜 欢 的 饮 料 连 边 , 流 量 是 这 种 字 符 串 个 数 , 权 值 是 4 − i Ⅱ.每种字符串向对应的第i喜欢的饮料连边,流量是这种字符串个数,权值是4-i Ⅱ.每种字符串向对应的第i喜欢的饮料连边,流量是这种字符串个数,权值是4−i
Ⅲ . 3 种 饮 料 分 别 向 汇 点 连 边 , 流 量 无 限 , 权 值 是 0 Ⅲ.3种饮料分别向汇点连边,流量无限,权值是0 Ⅲ.3种饮料分别向汇点连边,流量无限,权值是0
跑 模 板 就 好 跑模板就好 跑模板就好
#include
using namespace std;
const int maxn=2e5+10;
const int inf=1e9;
int a,b,c;
int t,n,ss,tt,vis[12],dis[maxn],maxcost,inflow[maxn],pre[maxn];
struct p{
int to,nxt,flow,w;
}d[maxn]; int head[maxn],cnt=1;
void add(int u,int v,int flow,int w){
d[++cnt]=(p){v,head[u],flow,w},head[u]=cnt;
d[++cnt]=(p){u,head[v],0,-w},head[v]=cnt;
}
string s,zi[9]={"2","012","021","102","120","201","210"};
bool spfa()
{
queueq;
for(int i=0;i<=10;i++) dis[i]=-1e9;
memset(vis,0,sizeof(vis));
q.push(ss);
dis[ss]=0,vis[ss]=1,inflow[ss]=inf;
while( !q.empty() )
{
int u=q.front(); q.pop();
vis[u]=0;
for(int i=head[u];i;i=d[i].nxt)
{
int v=d[i].to;
if( !d[i].flow ) continue;
if( dis[v]> t;
while( t-- )
{
memset(head,0,sizeof(head));
cin >> n >> a >> b >> c;
for(int i=1;i<=n;i++)
{
cin >> s;
for(int j=1;j<=6;j++)
if( s==zi[j] ) vis[j]++;
}
ss=0,tt=10,maxcost=0,cnt=1;
for(int i=1;i<=6;i++) add(ss,i,vis[i],0);
for(int i=1;i<=6;i++)
for(int j=0;j<=2;j++)
{
if( zi[i][j]=='0' ) add(i,7,inf,3-j);
else if( zi[i][j]=='1' ) add(i,8,inf,3-j);
else add(i,9,inf,3-j);
}
add(7,tt,a,0);
add(8,tt,b,0);
add(9,tt,c,0);
dinic();
cout << maxcost << endl;
}
}