SPOJ1693 COCONUTS - Coconuts

本文探讨了如何使用最小割模型解决特定问题,通过构建网络流图来确定最佳决策路径。介绍了对于每个人的选择和基友关系之间的代价,以及如何通过最小割算法找到最低总代价。同时,提供了详细的代码实现,包括初始化网络、广度优先搜索和最大流算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

传送门[洛谷]

自闭QAQ 什么玩意QAQ

不是很理解到底在干啥 问了巨佬以后大概是这个样子的

可以看出是最小割模型

对于每一个人 反悔的话就是代价+1

那么连接(s,i) (i,t)分别表示他最后选择赞同还是反对

根据初始状态来填代价

然后针对基友关系 他们之间连 代价为1的无向边

为什么是无向边呢 是因为 他们无论双方在哪个方向反对 只要不属于同一边的话就是有代价的

 

Edelweiss的PDF里还有这样的一个小补充

对于求一个函数\sum |1-x_i|*|p_i-v_0| +\sum x_i *|p_i-v_1| +\sum |x_i-x_j| *|p_i-p_j| 的最小值(其中x_i \epsilon \{0,1\}

对于(二者取其一)(不同有代价)这样的模型我们也可以用类似的方法建立最小割来求解

比较有趣。附代码。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define inf 20021225
#define ll long long
#define mxm 360010
#define mxn 310
using namespace std;

struct edge{int to,lt,f;}e[mxm];
int in[mxn],s,t,cnt=1,dep[mxn];
void add(int x,int y,int f)
{
	e[++cnt].to=y;e[cnt].lt=in[x];e[cnt].f=f;in[x]=cnt;
	e[++cnt].to=x;e[cnt].lt=in[y];e[cnt].f=0;in[y]=cnt;
}
queue<int> que;
bool bfs()
{
	memset(dep,0,sizeof(dep));
	dep[s]=1;while(!que.empty())	que.pop();
	que.push(s);
	while(!que.empty())
	{
		int x=que.front();que.pop();
		for(int i=in[x];i;i=e[i].lt)
		{
			int y=e[i].to;if(dep[y]||!e[i].f)	continue;
			dep[y]=dep[x]+1;que.push(y);
			if(y==t)	return true;
		}
	}
	return false;
}
int dfs(int x,int flow)
{
	if(x==t||!flow)	return flow;
	int cur=flow;
	for(int i=in[x];i;i=e[i].lt)
	{
		int y=e[i].to;
		if(dep[y]==dep[x]+1&&e[i].f)
		{
			int tmp=dfs(y,min(e[i].f,cur));
			cur-=tmp;e[i].f-=tmp;e[i^1].f+=tmp;
			if(!cur)	return flow;
		}
	}
	dep[x]=-1;return flow-cur;
}
int dinic()
{
	int ans=0;
	while(bfs())
		ans+=dfs(s,inf);
	return ans;
}
int main()
{
	int n,m,x,y;
	while(scanf("%d%d",&n,&m))
	{
		if(n==0&&m==0)	 break;
		s=n+1;t=s+1;
		memset(in,0,sizeof(in));
		cnt=1;
		for(int i=1;i<=n;i++)
		{
			scanf("%d",&x);
			if(x)	add(s,i,1),add(i,t,0);
			else	add(s,i,0),add(i,t,1);
		}
		for(int i=1;i<=m;i++)
		{
			scanf("%d%d",&x,&y);
			add(x,y,1);add(y,x,1);
		}
		printf("%d\n",dinic());
	}
	return 0;
}

 

转载于:https://www.cnblogs.com/hanyuweining/p/10321922.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值