博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ 1934 [Shoi2007]Vote 善意的投票 最小割
阅读量:5341 次
发布时间:2019-06-15

本文共 2421 字,大约阅读时间需要 8 分钟。

1934: [Shoi2007]Vote 善意的投票

Time Limit: 1 Sec  Memory Limit: 64 MB
Submit: 1444  Solved: 878
[][][]

Description

幼儿园里有n个小朋友打算通过投票来决定睡不睡午觉。对他们来说,这个问题并不是很重要,于是他们决定发扬谦让精神。虽然每个人都有自己的主见,但是为了照顾一下自己朋友的想法,他们也可以投和自己本来意愿相反的票。我们定义一次投票的冲突数为好朋友之间发生冲突的总数加上和所有和自己本来意愿发生冲突的人数。 我们的问题就是,每位小朋友应该怎样投票,才能使冲突数最小?

Input

第一行只有两个整数n,m,保证有2≤n≤300,1≤m≤n(n-1)/2。其中n代表总人数,m代表好朋友的对数。文件第二行有n个整数,第i个整数代表第i个小朋友的意愿,当它为1时表示同意睡觉,当它为0时表示反对睡觉。接下来文件还有m行,每行有两个整数i,j。表示i,j是一对好朋友,我们保证任何两对i,j不会重复。

Output

只需要输出一个整数,即可能的最小冲突数。

Sample Input

3 3
1 0 0
1 2
1 3
3 2

Sample Output

1

HINT

在第一个例子中,所有小朋友都投赞成票就能得到最优解

Source

最小冲突:最小割

建模:S-不同意_朋友_同意-T

//1085422276#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std ;typedef long long ll;#define mem(a) memset(a,0,sizeof(a))#define meminf(a) memset(a,127,sizeof(a));#define memfy(a) memset(a,-1,sizeof(a))#define TS printf("111111\n");#define FOR(i,a,b) for( int i=a;i<=b;i++)#define FORJ(i,a,b) for(int i=a;i>=b;i--)#define READ(a,b,c) scanf("%d%d%d",&a,&b,&c)#define inf 10000000#define maxn 300+10inline ll read(){ ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-')f=-1; ch=getchar();} while(ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();} return x*f;}//****************************************struct ss{ int to,u,next,v;}e[maxn*20000];int n,m;int S=0,T=301;int head[maxn],t,ans,d[maxn];void add(int u,int v,int w){ e[t].to=v; e[t].next=head[u]; e[t].v=w; head[u]=t++;}void init(){ mem(head);t=1;}int dfs(int x,int f){ if(x==T)return f; int w,used=0; for(int i=head[x];i&&f;i=e[i].next) { if(e[i].v>0&&d[e[i].to]==d[x]+1) { w=dfs(e[i].to,min(f-used,e[i].v)); used+=w; e[i].v-=w; e[i^1].v+=w; if(used==f)return f; } } if(!used)d[x]=-1; return used;}bool bfs(){ queue
q; memfy(d); d[S]=0; q.push(S); while(!q.empty()) { int k=q.front(); q.pop(); for(int i=head[k];i;i=e[i].next) { if(d[e[i].to]==-1&&e[i].v>0) { d[e[i].to]=d[k]+1; q.push(e[i].to); } } } return d[T]!=-1;}void dinic(){ ans=0; while(bfs())ans+=dfs(S,inf);}int main(){ int a,b; init(); scanf("%d%d",&n,&m); FOR(i,1,n) { scanf("%d",&a); if(a==1) { add(S,i,1); add(i,S,1); } else add(i,T,1),add(T,i,1); } FOR(i,1,m) { scanf("%d%d",&a,&b); add(a,b,1);add(b,a,1); } dinic(); cout<
<
代码

 

转载于:https://www.cnblogs.com/zxhl/p/4799131.html

你可能感兴趣的文章
How to Find Research Problems
查看>>
Linux用户管理
查看>>
数据库第1,2,3范式学习
查看>>
《Linux内核设计与实现》第四章学习笔记
查看>>
使用iperf测试网络性能
查看>>
struts2入门之准备工作
查看>>
从C语言的弱类型属性说起
查看>>
图片的显示隐藏(两张图片,默认的时候显示第一张,点击的时候显示另一张)...
查看>>
Docker 安装MySQL5.7(三)
查看>>
python 模块 来了 (调包侠 修炼手册一)
查看>>
关于CSS的使用方式
查看>>
本地MongoDB服务开启与连接本地以及远程服务器MongoDB服务
查看>>
跨域解决方案之CORS
查看>>
学习RESTFul架构
查看>>
分析语句执行步骤并对排出耗时比较多的语句
查看>>
原生JS轮播-各种效果的极简实现
查看>>
软件工程总结作业---提问回顾与个人总结
查看>>
计数器方法使用?
查看>>
带你全面了解高级 Java 面试中需要掌握的 JVM 知识点
查看>>
sonar结合jenkins
查看>>