洛谷P2057 【SHOI2007】善意的投票

题目链接

这道题是最小割的一个经典应用:划分集合。

题目的意思就是就是将所有的小朋友分为两个集合:同意睡觉和不同意睡觉的。不同的集合之间的边都要断开。

我们设\(S\)为投票结果为不想睡觉的小朋友(颜色为0)的集合;\(T\)为投票结果为想睡觉的小朋友(颜色为1)的集合。然后对于一个小朋友\(i\),设他的“颜色”为x,那么我们就连两条边\((S,i,[x!=0]),(i,T,[x!=1])\)。第一条边表示该小朋友属于\(S\)集合,第二条边表示该小朋友属于\(T\)集合。

因为投与自己意愿相反的票会产生冲突,所以需要给定流量。

然后对于一对好朋友\(i,j\),我们连\((i,j,1)\)的双向边。

实际操作中,流量为0的边自然可以不连。

答案就是最小割。这是因为,如果\(S\)和\(T\)之间还有流量,说明还有至少一对有冲突的好朋友存在。从这个角度来想,那么答案和最小割等价的。

如果要问最后小朋友们投的是那些票,那就看最小割割的是哪些边。如果割的是\((i,j)\),表示保留冲突。如果割的是\((s,i)\)或\((i,T)\),表示\(i\)投了意愿相反的票。

代码:

#include<bits/stdc++.h>
#define ll long long
#define N 305using namespace std;
inline int Get() {int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}while('0'<=ch&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;}int n,m;
int S,T;
struct load {int to,next;int flow;
}s[N*N<<2];
int h[N],cnt=1;
void add(int i,int j,int flow) {s[++cnt]=(load) {j,h[i],flow};h[i]=cnt;s[++cnt]=(load) {i,h[j],0};h[j]=cnt;
}
int dis[N],gap[N];
int dfs(int v,int maxf) {if(v==T) return maxf;int ret=0;for(int i=h[v];i;i=s[i].next) {int to=s[i].to;if(s[i].flow&&dis[to]+1==dis[v]) {int dlt=dfs(to,min(maxf-ret,s[i].flow));s[i].flow-=dlt;s[i^1].flow+=dlt;ret+=dlt;if(ret==maxf||dis[S]>=n+2) return ret;}}if(!(--gap[dis[v]])) dis[S]=n+2;gap[++dis[v]]++;return ret;
}
int sap() {memset(gap,0,sizeof(gap));memset(dis,0,sizeof(dis));gap[0]=n+2;int ans=0;while(dis[S]<n+2) ans+=dfs(S,1<<29);return ans;
}
void Init() {cnt=1;memset(h,0,sizeof(h));
}int main() {n=Get(),m=Get(); Init();T=n+1;for(int i=1;i<=n;i++) {int a=Get();if(a==1) add(S,i,1);else add(i,T,1);}for(int i=1;i<=m;i++) {int a=Get(),b=Get();add(a,b,1),add(b,a,1);}cout<<sap()<<"\n";return 0;
}

转载于:https://www.cnblogs.com/hchhch233/p/10071485.html

洛谷P2057 【SHOI2007】善意的投票相关推荐

  1. [洛谷P2057][SHOI2007]善意的投票

    题目大意:有$n(n\leqslant300)$个人,每个人可以选择$0$或$1$,每个人最开始有意愿,有$m(m\leqslant\dfrac{n(n-1)}2)$对好朋友.定义一次的冲突数为好朋友 ...

  2. 洛谷 - P2057 [SHOI2007]善意的投票 / [JLOI2010]冠军调查(最大流最小割)

    题目链接:点击查看 题目大意:有 n 个人,每个人都有两种意见,且有许多朋友,需要让朋友之间的意见尽可能统一,问最少有多少冲突 题目分析:因为每个人有两种意见,所以分别将其与源点和汇点相连,因为最后可 ...

  3. P2057 [SHOI2007]善意的投票 (最大流最小割)

    P2057 [SHOI2007]善意的投票 / [JLOI2010]冠军调查 最小割,两种意见可以看作源点S和T,我们需要做的是割最少的边使得S和T成为两个不同的集合,解释:割掉的边相当于1次冲突(因 ...

  4. P2057 [SHOI2007]善意的投票 最小割

    题意大致就是有n个人有两种不同的意见并且有许多朋友,需要让朋友间尽可能的统一意见(少发生冲突),如果一个人违反自己的本意也算冲突,求最少的冲突... 很明显是最小割   跑最大流算出冲突数 两种意见可 ...

  5. 洛谷 P2057 善意的投票

    题目描述 幼儿园里有n个小朋友打算通过投票来决定睡不睡午觉.对他们来说,这个问题并不是很重要,于是他们决定发扬谦让精神.虽然每个人都有自己的主见,但是为了照顾一下自己朋友的想法,他们也可以投和自己本来 ...

  6. 洛谷 - P2163 [SHOI2007]园丁的烦恼(不带修二维数点-树状数组/主席树)

    题目链接:点击查看 题目大意:二维平面坐标系中给出 nnn 个坐标点,然后是 mmm 次询问,每次询问需要回答一个闭合矩阵中有多少个点 题目分析:想挂树套树来着,但是复杂度有点大.本题不带修且可以离线 ...

  7. 洛谷 P2163 [SHOI2007]园丁的烦恼 (离线sort,树状数组,解决三维偏序问题)

    P2163 [SHOI2007]园丁的烦恼 题目描述 很久很久以前,在遥远的大陆上有一个美丽的国家.统治着这个美丽国家的国王是一个园艺爱好者,在他的皇家花园里种植着各种奇花异草. 有一天国王漫步在花园 ...

  8. 洛谷 P2163 [SHOI2007]Tree 园丁的烦恼

    此题树状数组卡常好题(滑稽) 题目描述 很久很久以前,在遥远的大陆上有一个美丽的国家.统治着这个美丽国家的国王是一个园艺爱好者,在他的皇家花园里种植着各种奇花异草.有一天国王漫步在花园里,若有所思,他 ...

  9. SHOI2007善意的投票

    水题 最小割问题 考察什么? 冲突. 这种题不是没有过啊 有一个就是激光打别人的就是利用这个思想(搞忘做题解了,结果没权限了WOC) 利用S-T表示若联通则依旧有冲突 把S表示赞成,T表示不赞成 赞成 ...

最新文章

  1. P1067 多项式输出(模拟)
  2. 控制台编写JAVA程序教程_写一个java程序的步骤是什么?写java程序技巧
  3. 明明还有空间,硬盘却写不进去了!
  4. 电压压力蕊片_陶瓷压力传感器工作原理、结构及分类
  5. 【专家访谈】测试专家 - 陈林钧 访谈记录整理汇总
  6. python把字典转换成json字符串
  7. Linux 常用命令十四 killall和pkill
  8. win10杜比全景声评测_Win10安装杜比全景声音效教程
  9. 如何将新手引导模块化?答案在此
  10. 软考:软件设计师(中级)--学习笔记02操作系统基本原理
  11. python hdf5_Python HDF5属性
  12. Flutter 无法热重载
  13. 科三考试邢台市交安考试路线
  14. 忆恩师刘自朗,我的高中物理老师
  15. 基于asp.net的幼儿园宣传网站管理系统#毕业设计#课程设计
  16. pdf ppt word office转图片 教学白板
  17. python12306买票_Python-爬虫-12306购票业务实现
  18. python中for循环列表_如何通过Python中的for循环传递列表列表?
  19. arm linux:添加对挂载ntfs和exfat格式u盘的支持(petalinux)
  20. 【Scikit-Learn】使用k-均值对文档进行聚类分析

热门文章

  1. 描述Linux的虚拟化实现,Linux中实现虚拟化的四种常用方法
  2. 如何保证两个不同宽高的canvas用同一组坐标正常显示_如何1人5天开发完3D数据可视化大屏 【一】...
  3. hellowolrd 的系统调用
  4. linux find命令的日常使用
  5. python3 学习使用大纲梳理
  6. 新手焊接电路板_【实验】新手焊接电路板的不完全指南
  7. MATLAB批量实现dicom转换为bmp格式
  8. 【 Vivado 】时钟组(Clock Groups)
  9. SQL数据库学习之路(九)
  10. FAQ系列 | 监控平均SQL响应时长