2020百度之星初赛二:Drink(费用流)

由 于 每 个 人 只 能 匹 配 一 种 饮 料 由于每个人只能匹配一种饮料

所 以 可 以 看 成 匹 配 问 题 , 并 且 匹 配 有 权 值 , 所 以 用 最 大 费 用 最 大 流 所以可以看成匹配问题,并且匹配有权值,所以用最大费用最大流 ,,

Ⅰ . 源 点 向 6 种 字 符 串 连 边 , 流 量 无 限 大 , 权 值 为 0 Ⅰ.源点向6种字符串连边,流量无限大,权值为0 .6,,0

Ⅱ . 每 种 字 符 串 向 对 应 的 第 i 喜 欢 的 饮 料 连 边 , 流 量 是 这 种 字 符 串 个 数 , 权 值 是 4 − i Ⅱ.每种字符串向对应的第i喜欢的饮料连边,流量是这种字符串个数,权值是4-i .i,,4i

Ⅲ . 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;
	}
}

你可能感兴趣的:(CF刷题计划)