随笔分类 -  图论

摘要:由上一篇可得最大权闭合图的权值为sum-max_flowsum为正的权值和,max_flow为重新建图后的最大流求最大流后,在残留网络中从s出发dfs能搜到点都为最大权闭合图中的点,即这个最小割对应的是最大权闭合图View Code #include<stdio.h>#include<string.h>const int MAX=100005;const int INF=1000000000;struct{ int v,c,next;}edge[1000000];int E,head[MAX];int gap[MAX],cur[MAX];int pre[MAX],dis 阅读全文
posted @ 2012-03-12 23:35 Because Of You 阅读(851) 评论(0) 推荐(0) 编辑
摘要:[网络流]最大权闭合图(转载)来自:http://hi.baidu.com/%C6%AE%BB%A8%C4%EA%B4%FA/blog/item/45d4bb1765e7044721a4e960.html以下内容参考 胡伯涛 《最小割模型在信息学竞赛中的应用》,感谢他为我们提供这么优秀的论文。看不懂以上论文的同学,可以试试看一下以下内容,本文无大量的数学符号,方便阅读理解。首先我们由一道题来引入,见[线性规划与网络流24题 2] 太空飞行计划问题。这道题中,实验依赖于仪器,而实验和仪器都有权值,且仪器为负,实验为正。这里闭合图的概念就很好引出了。在一个图中,我们选取一些点构成集合,记为V,且集 阅读全文
posted @ 2012-03-12 16:10 Because Of You 阅读(14169) 评论(3) 推荐(20) 编辑
摘要:网上摘的一些知识点基础知识 欧拉回路是图G中的一个回路,经过每条边有且仅一次,称该回路为欧拉回路。具有欧拉回路的图称为欧拉图,简称E图。 无向图中存在欧拉回路的条件:每个点的度数均为偶数。 有向图中存在欧拉回路的条件:每个点的入度=出度。 欧拉路径比欧拉回路要求少一点: 无向图中存在欧拉路径的条件:每个点的度数均为偶数或者有且仅有2个度数为奇数的点。 有向图中存在欧拉路径的条件:除了2个点外,其余的点入度=出度,且在这2个点中,一个点的入度比出度大1,另一个出度比入度大1。 欧拉路径的输出:经典的套圈算法。 下面来重点讲讲混合图的欧拉回路问题。 混合图就是边集中有有向边和无向边同时存在。这时候 阅读全文
posted @ 2012-03-12 11:26 Because Of You 阅读(573) 评论(0) 推荐(0) 编辑
摘要:两种做法1:本来想的是枚举每个点u,从s搜到u,再从t搜到u,如果两条路径只有u这一个公共点,则u可以在简单路径上,后来举出了一个反例就推翻掉了,囧。。。。。。但现在发现这个想法是下一个想法的铺垫。模型是:是否存在s->u的一条路径与t->u的另一条路径只有u这一个交点单纯的搜索很难弄,比如广搜,搜到的路径都是最短路径,很容易就可以举出反例推翻掉。举个例子:先发一张比较挫的图片这个例子中,每个点都可以成为s->t的简单路径上的点,所以答案是0.如果用搜索,很可能s->y->v->u t->v->u,而忽略了s->y->x->u导 阅读全文
posted @ 2012-03-11 23:39 Because Of You 阅读(578) 评论(0) 推荐(0) 编辑
摘要:题目要求至少添加几条边才能使去掉人和一条边后,图还是连通的首先进行双连通缩点,一个连通块就相当于新图中的一个点新的图形成了一棵树要想添加若干条边后任意去掉一条原图中的边后图还是连通的,我们应该将叶子连起来,使得任何一个叶子都有连接到别的叶子的边很显然,叶子总数cnt为偶数时,答案为cnt/2;叶子总数为奇数时,答案为(cnt+!)/2;View Code #include<stdio.h>#include<queue>#include<string.h>#include<vector>using namespace std;const int m 阅读全文
posted @ 2012-03-11 19:57 Because Of You 阅读(333) 评论(0) 推荐(0) 编辑
摘要:假设最长链是s-t,任意从一个点开始搜索,能搜到的最远的点肯定是s、t中的一个,然后再从搜到的最远点搜一遍,从这个店到能搜到的最远的点的路径就是最长链详细证明改天再写View Code #include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn = 100010;int head[maxn];struct Edge{ int v,w,next;}edge[maxn*2];bool vis[maxn];int dis[maxn];int n,m;i 阅读全文
posted @ 2012-03-10 00:05 Because Of You 阅读(1058) 评论(0) 推荐(0) 编辑
摘要:类型:无源汇可行流参考自()http://hi.baidu.com/evelynhe/blog/item/f1c5ba2fcbe674271e3089ad.html每条边的容量满足一定的限制,即有一个上限值,也有一个下限值上界用ci表示,下界用bi表示。下界是必须流满的,那么对于每一条边,去掉下界后,其自由流为ci– bi。主要思想:每一个点流进来的流=流出去的流对于每一个点i,令Mi= sum(i点所有流进来的下界流)– sum(i点所有流出去的下界流)如果Mi大于0,代表此点必须还要流出去Mi的自由流,那么我们从源点连一条Mi的边到该点。如果Mi小于0,代表此点必须还要流进来Mi的自由流, 阅读全文
posted @ 2012-02-29 16:24 Because Of You 阅读(1020) 评论(0) 推荐(0) 编辑
摘要:求的最大流后依次从源点和汇点开始dfs 如果能搜到的点数之和等于总的点数,最小割唯一,否则不唯一View Code #include<stdio.h>#include<string.h>const int MAX=100005;const int INF=1000000000;struct{ int v,c,next;}edge[1000000];int E,head[MAX];int gap[MAX],cur[MAX];int pre[MAX],dis[MAX];void add_edge(int s,int t,int c,int cc){/*加边的时候同时加两条, 阅读全文
posted @ 2012-02-27 16:28 Because Of You 阅读(352) 评论(0) 推荐(0) 编辑
摘要:由行向列建图,增加两个源汇点,源点向行连边,容量为该行的花费,列向汇点连边,容量为该列的代价,一个伞兵的位置为x,y,则从x行向y列连一天容量为无穷大的边,最后求最大流(最小割的容量)即可View Code #include<cstdio>#include<cstring>#include<cmath>const int MAX=100005;const double INF=1000000000;struct{ int v,next; double c;}edge[1000000];int E,head[MAX];int gap[MAX],cur[MAX] 阅读全文
posted @ 2012-02-27 15:50 Because Of You 阅读(235) 评论(0) 推荐(0) 编辑
摘要:模板题,不解释了 阅读全文
posted @ 2012-02-22 16:04 Because Of You 阅读(195) 评论(0) 推荐(0) 编辑
摘要:首先注意边是双向边,最短路的inf要取很大思路:增加一个源点,一个汇点,如果一个避雨点有a只奶牛,则从源点向这个点连一条边,容量为a,如果这个避雨点能容纳b只奶牛,则从这个点向汇点连一条容量为b的边。接着二分枚举答案,两点间最短路径的长度小于等于二分值的两个点能互相到达,连一条容量为无穷大的边这样子建好图后求最大流会发现样例都过不了,debug过程中发现如果1->2 , 2->3,那么1就会自动联通3,实际上1,3可能不连通,所以想到把点拆成两排,如果1,2连通,就从1连一条边到2+n,这样就不会出现上面的情况了,另外,连接汇点的点变成了n+1---2*n。敲完后果断还是WA,都快 阅读全文
posted @ 2012-02-22 15:18 Because Of You 阅读(427) 评论(0) 推荐(0) 编辑
摘要:hdu 2768,两个投票者矛盾的话就连一条边,总数减去最大匹配数就是要求的答案#include<cstdio>#include<cstring>#include<string>#include<vector>#include<iostream>using namespace std;bool vis[501];int match[501];vector<int> g[501];string a[505],b[505];bool dfs(int u){ for(int i=0;i<g[u].size();i++) { 阅读全文
posted @ 2012-02-18 19:22 Because Of You 阅读(753) 评论(1) 推荐(0) 编辑
摘要:题意,一个图,要将每条边恰好遍历两遍,而且要以不同的方向,还要回到原点。直接dfs一下就好了,vis[]标记边是否访问,不会的仔细模拟一遍哪个dfs就好了View Code #include<stdio.h>#include<string.h>struct Edge{ int v,next;}edge[111111];int head[11111];int n,m,tot;bool vis[111111];void add(int s,int t){ edge[tot].v=t; edge[tot].next=head[s]; head[s]=tot++;}void d 阅读全文
posted @ 2011-12-22 11:18 Because Of You 阅读(215) 评论(0) 推荐(0) 编辑
摘要:推荐java学习室http://www.java3z.com/cwbwebhome/旧题新做,练java用View Code import java.io.*;import java.util.*;import java.math.*;public class Main{ static int n,m,match[]=new int[210]; static boolean mat[][]=new boolean [210][210],v[]=new boolean[210]; static boolean dfs(int pre) { int i; ... 阅读全文
posted @ 2011-12-19 14:04 Because Of You 阅读(307) 评论(0) 推荐(0) 编辑
摘要:相邻的房子间至少要有1的距离,高度相邻的房子间最多能距离d,根据这些条件建图后,要注意一点要看1和n的相对位置,如果1在n的左边,求1到n的最短路,dis【n】就是答案(排除无解);否则求n到1的最短路,dis【1】就是答案错了好几次,inf设的不够大。。。。。View Code #include<stdio.h>#include<string.h>#include<queue>#include<algorithm>using namespace std;struct node { int h,id;}p[1010];const int INF 阅读全文
posted @ 2011-12-10 18:13 Because Of You 阅读(411) 评论(0) 推荐(0) 编辑
摘要:在别人的和擦粉约束列表里搜到的这题,看完题目果断感觉是水题根据s[b]-s[a]<=c来建图最后是求s[n]-s[1]的最大值,从1出发走一遍到n的最短路径就好但是超时了,果断不能接受。。。。别人的做法:用栈来代替spfa的队列,或者用dijkstra+heap来做。。晕倒,总之,又学到了一点。。。View Code #include<stdio.h>#include<stack>#include<string.h>using namespace std;const int INF = 9999999;struct NODE{ int v,w; int 阅读全文
posted @ 2011-12-09 17:38 Because Of You 阅读(284) 评论(0) 推荐(0) 编辑
摘要:与intervals那题不同的是这题的点围成了一个圆0、1、2、3、4.。。。23、0一个巧妙地想法是增加一个点24,其他就和intervals那题差不多了,根据约束条件来建图View Code #include<stdio.h>#include<queue>#include<string.h>using namespace std;const int INF = 9999999;struct NODE{ int v,w; int next;}list[10000];int tot;int head[30];int dis[30];int vis[30];i 阅读全文
posted @ 2011-12-09 16:24 Because Of You 阅读(216) 评论(0) 推荐(0) 编辑
摘要:差分约束巧妙地将不等式的关系转换成图论中求最短路径时所用的三角形不等式即如果dis[i]+map[i][j]<=dis[j]交换一下得:dis[i]-dis[j]<=-map[i][j]建边j->i 权值为-map[i][j];核心的方法就是上面的东西了用spfa求最短路View Code #include<stdio.h>#include<queue>#include<string.h>using namespace std;const int INF = 9999999;struct NODE{ int v,w; int next;}l 阅读全文
posted @ 2011-12-07 16:47 Because Of You 阅读(207) 评论(0) 推荐(0) 编辑
摘要:关键点:对每个箱子的dimension 排个序,这样才能判断某个箱子是否真的能放入另一个箱子内建好图后求一个图中的最长路即可View Code #include<stdio.h>#include<string.h>#include<algorithm>using namespace std;const int inf = 100000000;int box[510][1010];int map[510][510];int n,d;bool ok;int count=0;bool solve(int a,int b){ int i,j; bool flag=t 阅读全文
posted @ 2011-12-06 22:01 Because Of You 阅读(395) 评论(0) 推荐(0) 编辑
摘要:中文题目竟然理解错了题意关键点:等级差距大于m的两个人不能直接或间接交易,而1必须是图的终点,所以最短路径中所有的点的等级都必须在【level【1】-m,level【1】+m】之间,所以可以枚举等级限制,for(i=level[1]-m;i<=level[1];i++){ 最短路算法且要保证 最短路径中每个点的等级都在【i,i+m】之间}就这样,带血的AC总是那么的鼓舞人心View Code #include<stdio.h>#include<string.h>#include<stdlib.h>const int inf = 1000000000;i 阅读全文
posted @ 2011-12-06 12:31 Because Of You 阅读(446) 评论(0) 推荐(0) 编辑