网络流合集:bzoj1433,1934,1854 题解
转载请注明:http://blog.csdn.net/jiangshibiao/article/details/23992205
网络流/二分图大合集
【NO.1*原题】
1433: [ZJOI2009]假期的宿舍
Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 972 Solved: 422
[Submit][Status]
Description

Input

Output

Sample Input
3
1 1 0
0 1 0
0 1 1
1 0 0
1 0 0
Sample Output
HINT
对于30% 的数据满足1 ≤ n ≤ 12。
对于100% 的数据满足1 ≤ n ≤ 50,1 ≤ T ≤ 20。
【NO.1*分析】想了非常长时间。igzhou大神非要我用二分图写,但我就是要转化成网络流。首先我们把住校的人(也就是有床的人)的床和汇点T连边。注意这是”床“。而不是人本身。
然后把源点S和全部人连一条边。
再把互相认识的人中人和床连边。
比方1是住校的,2是走读的。2认识1,就把2和1的床连边。
注意不是2和1连边。
自然,对于住校生。自己和自己的床也要连边。
以上全部边的容量都是1。
坑点:输出不用回车。
【NO.1*代码】
#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 305
#define INF 2000000000
using namespace std;
int map[N][N],f[N],q[N],num[N],x,test,ans,n,m,i,j,cnt;
bool bfs()
{
memset(f,-1,sizeof(f));
int h=0,t=1;q[1]=0;f[0]=1;
while (h<t)
{
int now=q[++h];if (now==n) return 1;
for (int i=0;i<=n;i++)
if (map[now][i]&&f[i]==-1)
{
f[i]=f[now]+1;q[++t]=i;
}
}
return 0;
}
int dinic(int sta,int sum)
{
if (sta==n) return sum;
int os=sum;
for (int i=0;(i<=n)&&os;i++)
if (map[sta][i]&&f[i]==f[sta]+1)
{
int Min=dinic(i,min(map[sta][i],os));
map[sta][i]-=Min;map[i][sta]+=Min;os-=Min;
}
if (os==sum) f[sta]=-1;
return sum-os;
}
int main()
{
scanf("%d",&test);
while (test)
{
test--;memset(map,0,sizeof(map));
scanf("%d",&n);cnt=0;
for (i=1;i<=n;i++)
{
scanf("%d",&num[i]);
if (num[i]) map[i+n][2*n+1]=1;
}
for (i=1;i<=n;i++)
{
scanf("%d",&x);
if (!num[i]||num[i]&&!x) map[0][i]=1,cnt++;
}
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
{
scanf("%d",&x);
if (x||i==j) map[i][j+n]=1;
}
n=2*n+1;ans=0;
while (bfs()) ans+=dinic(0,INF);
if (ans==cnt) puts("^_^");else puts("T_T");
}
return 0;
}
【NO.2*原题】
1934: [Shoi2007]Vote 善意的投票
Time Limit: 1 Sec Memory Limit: 64 MB id=1934" style="color:blue; text-decoration:none">Status
Submit: 897 Solved: 537
[Submit][
Description
我们定义一次投票的冲突数为好朋友之间发生冲突的总数加上和全部和自己本来意愿发生冲突的人数。 我们的问题就是,每位小朋友应该如何投票,才干使冲突数最小?
Input
接下来文件还有m行,每行有两个整数i,j。
表示i,j是一对好朋友,我们保证不论什么两对i,j不会反复。
Output
Sample Input
1 0 0
1 2
1 3
3 2
Sample Output
HINT
在第一个样例中,全部小朋友都投赞成票就能得到最优解
Source
【NO.2*分析】我感觉这个的建图有点诡异。把全部1的小朋友和S连,否则和T连。再朋友间互相连。求最大流。
【NO.2*代码】
#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 302
#define INF 2000000000
using namespace std;
int map[N][N],f[N],q[N],num,x,y,ans,n,m,i;
bool bfs()
{
memset(f,-1,sizeof(f));
int h=0,t=1;q[1]=0;f[0]=1;
while (h<t)
{
int now=q[++h];if (now==n) return 1;
for (int i=0;i<=n;i++)
if (map[now][i]&&f[i]==-1)
{
f[i]=f[now]+1;
q[++t]=i;
}
}
return 0;
}
int dinic(int sta,int sum)
{
if (sta==n) return sum;int os=sum;
for (int i=0;(i<=n)&&os;i++)
if (map[sta][i]&&f[i]==f[sta]+1)
{
int Min=dinic(i,min(map[sta][i],os));
map[sta][i]-=Min;map[i][sta]+=Min;os-=Min;
}
if (os==sum) f[sta]=-1;return sum-os;
}
int main()
{
scanf("%d%d",&n,&m);
for (i=1;i<=n;i++)
{
scanf("%d",&num);if (num) map[0][i]=1;else map[i][n+1]=1;
}
for (i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);map[x][y]=map[y][x]=1;
}
n++;while (bfs()) ans+=dinic(0,INF);
printf("%d",ans);
return 0;
}
【NO.3*原题】
1854: [Scoi2010]游戏
Time Limit: 5 Sec Memory Limit: 162 MB id=1854" style="color:blue; text-decoration:none">Status
Submit: 1954 Solved: 689
[Submit][
Description
也就是说一開始的时候,lxhgww仅仅能使用某个属性值为1的装备攻击boss,然后仅仅能使用某个属性值为2的装备攻击boss,然后仅仅能使用某个属性值为3的装备攻击boss……以此类推。
如今lxhgww想知道他最多能连续攻击boss多少次?
Input
Output
Sample Input
1 2
3 2
4 5
Sample Output
HINT
【数据范围】
对于30%的数据。保证N < =1000
对于100%的数据,保证N < =1000000
Source
【NO.3*分析】这个构图是挺经典的。最后我是用二分图A的。
事实上这也挺好理解。左側是各种属性,右側是各种装备。对于每个装备,连两个属性。
这样就能保证选了一个后,对于同一个装备的还有一个属性,就不会选了。
【NO.3*代码】
#include<cstdio>
#include<cstring>
using namespace std;
struct arr{int go,next;}a[2000005];
int belong[1000005],end[10005];
int visit[1000005];
int x,y,n,i,cnt;
char ch;
void add(int x,int y)
{
a[++cnt].go=y;a[cnt].next=end[x];end[x]=cnt;
}
inline int Read()
{
while (ch<'0'||ch>'9') ch=getchar();
int s=0;while (ch>='0'&&ch<='9') s=s*10+ch-48,ch=getchar();return s;
}
bool find(int k)
{
for (int i=end[k];i;i=a[i].next)
{
int go=a[i].go;
if (visit[go]==i) continue;
visit[go]=i;
if (!belong[go]||find(belong[go]))
{
belong[go]=k;
return true;
}
}
return false;
}
int main()
{
scanf("%d",&n);ch=' ';
for (i=1;i<=n;i++)
{
x=Read();y=Read();
add(x,i);add(y,i);
}
memset(belong,0,sizeof(belong));
for (i=1;i<=10000;i++)
if (!find(i)) break;
i--;printf("%d",i);/
return 0;
}
网络流合集:bzoj1433,1934,1854 题解的更多相关文章
- 【合集】有标号的DAG图计数(合集)
[合集]有标号的DAG图计数(合集) orz 1tst [题解]有标号的DAG计数1 [题解]有标号的DAG计数2 [题解]有标号的DAG计数3 [题解]有标号的DAG计数4
- [题解+总结]动态规划大合集II
1.前言 大合集总共14道题,出自江哥之手(这就没什么好戏了),做得让人花枝乱颤.虽说大部分是NOIP难度,也有简单的几道题目,但是还是做的很辛苦,有几道题几乎没思路,下面一道道边看边分析一下. 2. ...
- [题解+总结]NOIP动态规划大合集
1.前言 NOIP2003-2014动态规划题目大合集,有简单的也有难的(对于我这种动态规划盲当然存在难的),今天就把这些东西归纳一下,做一个比较全面的总结,方便对动态规划有一个更深的理解. 2.NO ...
- 9.15 DP合集水表
9.15 DP合集水表 显然难了一些啊. 凸多边形的三角剖分 瞄了一眼题解. 和蛤蛤的烦恼一样,裸的区间dp. 设f[i][j]表示i~j的点三角剖分最小代价. 显然\(f[i][i+1]=0,f[i ...
- DP+贪心水题合集_C++
本文含有原创题,涉及版权利益问题,严禁转载,违者追究法律责任 本次是最后一篇免费的考试题解,以后的考试题目以及题解将会以付费的方式阅读,题目质量可以拿本次作为参考 本来半个月前就已经搞得差不多了,然后 ...
- 动态规划大合集II
1.前言 大合集总共14道题,出自江哥之手(这就没什么好戏了),做得让人花枝乱颤.虽说大部分是NOIP难度,也有简单的几道题目,但是还是做的很辛苦,有几道题几乎没思路,下面一道道边看边分析一下. 2. ...
- NOIP动态规划大合集
1.前言 NOIP2003-2014动态规划题目大合集,有简单的也有难的(对于我这种动态规划盲当然存在难的),今天就把这些东西归纳一下,做一个比较全面的总结,方便对动态规划有一个更深的理解. 2.NO ...
- SQL Server技术内幕笔记合集
SQL Server技术内幕笔记合集 发这一篇文章主要是方便大家找到我的笔记入口,方便大家o(∩_∩)o Microsoft SQL Server 6.5 技术内幕 笔记http://www.cnbl ...
- 【Android】开发中个人遇到和使用过的值得分享的资源合集
Android-Classical-OpenSource Android开发中 个人遇到和使用过的值得分享的资源合集 Trinea的OpenProject 强烈推荐的Android 开源项目分类汇总, ...
随机推荐
- VMware开启虚拟化实现CentOS创建KVM
参考: http://blog.csdn.net/liulove_micky/article/details/48343013
- readlink命令
转:http://blog.csdn.net/zz198808/article/details/9319479 readlink是linux系统中一个常用工具,主要用来找出符号链接所指向的位置. 在U ...
- 使用size()方法输出列表中的元素数量。需要注意的是,这个方法返回的值可能不是真实的,尤其当有线程在添加数据或者移除数据时,这个方法需要遍历整个列表来计算元素数量,而遍历过的数据可能已经改变。仅当没有任何线程修改列表时,才能保证返回的结果是准确的。
使用size()方法输出列表中的元素数量.需要注意的是,这个方法返回的值可能不是真实的,尤其当有线程在添加数据或者移除数据时,这个方法需要遍历整个列表来计算元素数量,而遍历过的数据可能已经改变.仅当没 ...
- CountDownLatch模拟高并发测试代码
直接上代码进行验证吧 /** * 通过countdownlatch的机制,来实现并发运行 * 模拟200个并发测试 * @author ll * @date 2018年4月18日 下午3:55:59 ...
- Intellij output 中文乱码
使用intellij有一段时间了,intellij output中文乱码,每次使用这两点解决,就可以解决乱码问题. 1.修改启动参数 修改安装Intellij目录下的C:\Program Files ...
- [Algorithms] Divide and Recurse Over an Array with Merge Sort in JavaScript
Merge sort is a recursive sorting algorithm. If you don't understand recursion, I recommend finding ...
- POJ 1144 Network(无向图连通分量求割点)
题目地址:id=1144">POJ 1144 求割点.推断一个点是否是割点有两种推断情况: 假设u为割点,当且仅当满足以下的1条 1.假设u为树根,那么u必须有多于1棵子树 2.假设u ...
- 在项目中引用android.support.v7
在Android开发中,新建的项目可能因为缺少对sopport工程的引用而报错,可以这样解决. 1.项目右键 --> import --> Android --> Existing ...
- cpu、内存、磁盘
例一:内存使用率 #!/bin/bash total=$(free -m|grep Mem|awk '{print $2}') used=$(free -m|grep Mem|awk '{print ...
- 改变UITextField的Placeholder颜色
通过 attributedPlaceholder 属性来改变 if([textField respondsToSelector:@selector(setAttributedPlaceholder:) ...