摘要: 思路:将以桥为分界的所有连通分支进行缩点,得到一颗树,求出树的直径。再用树上的点减去直径,再减一#pragma comment(linker, "/STACK:1024000000,1024000000")#include#include#include#include#include#include#define Maxn 210110#define Maxm 2501000using namespace std;int index[Maxn],vi[Maxn],dfn[Maxn],low[Maxn],e,n,lab=0,Stack[Maxn],top,num,head[ 阅读全文
posted @ 2013-07-25 21:09 fangguo 阅读(474) 评论(0) 推荐(0) 编辑
摘要: 思路:就是裸的最小树形图~#include#include#include#include#include#define Maxn 110#define LL double#define inf 1e9using namespace std;int pre[Maxn],id[Maxn],vi[Maxn],num;LL in[Maxn];struct Edge{ int u,v; LL val;}edge[Maxn*Maxn];struct Point{ double x,y;}p[Maxn];double Dis(Point a,Point b){ return sq... 阅读全文
posted @ 2013-07-25 17:06 fangguo 阅读(147) 评论(0) 推荐(0) 编辑
摘要: 思路:将所有的直线的两个端点和城市混在一起,将能直接到达的两个点连线,求一次floyd最短路径。二分枚举bag容量,然后按给的要先后占领的城市由前向后,把能到一步到达的建一条边。然后求一次最小路径覆盖,就是最少需要多少个士兵才能全部占领,跟给出的p值进行比较。#include#include#include#include#include#define Maxn 510#define Maxm Maxn*Maxn#define eps 1e-6#define inf 100000000using namespace std;int match[Maxn],vi[Maxn],graphic[Ma 阅读全文
posted @ 2013-07-25 09:18 fangguo 阅读(287) 评论(0) 推荐(0) 编辑
摘要: 思路:设sum(cost[i])/sum(dis[i])=r;那么要使r最小,也就是minsum(cost[i]-r*dis[i]);那么就以cost[i]-r*dis[i]为边权重新建边。当求和使得最小生成树的sum(cost[i]-r*dis[i])==0时,这个r就是最优的。这个证明是01分数规划。#include#include#include#include#include#define Maxn 1010#define Maxm Maxn*Maxn#define inf 1e16#define eps 1e-6using namespace std;int vi[Maxn],n;d 阅读全文
posted @ 2013-07-24 20:31 fangguo 阅读(207) 评论(0) 推荐(0) 编辑
摘要: 思路:利用dfs遍历整棵树,找出最长子树与次长子树,两者的和最大就是直径。若k值小于直径就输出k-1,否则输出(k-d-1)*2+d;#include#include#include#include#define Maxn 1000010using namespace std;int vi[Maxn],head[Maxn],ans,e;struct Edge{ int u,v,next,val;}edge[Maxn];void init(){ e=0; memset(head,-1,sizeof(head)); ans=0; memset(vi,0,sizeof(... 阅读全文
posted @ 2013-07-24 17:19 fangguo 阅读(179) 评论(0) 推荐(0) 编辑
摘要: 思路:首先将所有的查询有一个vector保存起来。我们从1号点开始dfs这颗二叉树,用线段树记录到当前节点时,走左节点的有多少比要查询该节点的X值小的,有多少大的,同样要记录走右节点的有多少比X小的,多少比X大的。小和大的x,y值题目给了。当要进行左儿子时,建该节点值插入走左的线段树,回退的时候将其删除,进入右儿子时将其插入走右的线段树,同样回退时删除。遍历完一个树,整个查询就做完了,最后输出。#include#include#include#include#include#include#define Maxn 200100#define lson(x) (x>1)#define in 阅读全文
posted @ 2013-07-24 17:13 fangguo 阅读(416) 评论(0) 推荐(0) 编辑
摘要: 思路:这题的感觉就是最长上升子序列的升级版。首先对于最长上升子序列要用n*log(n)的算法才行,这个复杂度的算法可以从hdu1025得到启发。然后就是什么情况下最优问题了。对于序列中某个数i,找出其后面最长不下降子序列长度和最长不上升子序列长度,将这两个长度加起来,最大的就是我们要找到。但由于存在相同值,那么我么就要确定这两个子序列中值为i的个数最少的那个,用上面求得和减去它。我的代码比较挫。#include#include#include#include#includeusing namespace std;int ans[200010],list[100010],low[100010], 阅读全文
posted @ 2013-07-23 22:14 fangguo 阅读(445) 评论(0) 推荐(0) 编辑
摘要: 思路:利用一个估计函数g[i]=dis[i]+len。其中len为队列出来的点当前已经走了的距离。dis[i]为该点到终点的最短路径。这样我们只要将点按g[i]的升序在队列你排序,每次取出最小的g[i]值的点。其意义就是每次找最短的能到终点的点。第一次找到就是最短路径,第二次就是就是第二短,第三次就是...顺推#include#include#include#include#include#include#define Maxn 1010#define Maxm 200200#define inf 10000000using namespace std;int dis[Maxn],vi[Max 阅读全文
posted @ 2013-07-23 17:05 fangguo 阅读(270) 评论(0) 推荐(0) 编辑
摘要: 思路:这个还是看的胡伯涛的论文《最小割在信息学竞赛中的应用》。是将最大密度子图问题转化为了01分数规划和最小割问题。直接上代码:#include #include #include #include #include #define Maxn 6010#define Maxm 200000#define LL double#define inf 100000000#define Abs(a) (a)>0?(a):(-a)using namespace std;struct Edge{ int from,to,next; LL val;}edge[Maxm];const double... 阅读全文
posted @ 2013-07-22 20:18 fangguo 阅读(215) 评论(0) 推荐(0) 编辑
摘要: 思路:这题考的是最大闭权图。只要知道怎么求最大闭权图就知道怎么做。但好像有点卡模版,要高效的模版才行。#include #include #include #define Maxn 6010#define Maxm 200000#define LL __int64#define Abs(a) (a)>0?(a):(-a)using namespace std;struct Edge{ int from,to,next; LL val;}edge[Maxm];LL value[Maxn],inf=0;int index[Maxn],work[Maxn],dis[Maxn],q[Max... 阅读全文
posted @ 2013-07-22 12:14 fangguo 阅读(220) 评论(0) 推荐(0) 编辑