摘要: 思路:这题的结论得要看amber的论文,结论就是将求f(x)/b(x)最小转化为求min(f(x)-b(x)*λ),其中x为S集的解空间,f(x)为解的边权和,b(x)为解的边数,λ=f(x)/b(x)。λ*为最优解,当且仅当(x属于S)∑min(f(x)-b(x)*λ)==0;故可以将原边权的权值改为w-λ;对λ进行二分枚举,找出答案。#include#include#include#include#include#define N 510#define M 50010#define inf 1e9using namespace std;const double eps=1e-9;struc 阅读全文
posted @ 2013-07-21 21:54 fangguo 阅读(208) 评论(0) 推荐(0) 编辑
摘要: 思路:每次枚举删除一个点,然后对剩下的点求出关键点,判断删除哪个关键点获得的连通分支数最大。#include#include#include#include#include#include#define Maxn 5100#define Maxm 50100#define inf 0x7fffffffusing namespace std;map p[Maxn];int Index[Maxn],dfn[Maxn],low[Maxn],vi[Maxn],compent[Maxn],e,n,lab,Max=0;struct Edge{ int from,to,next;}edge[Maxm]... 阅读全文
posted @ 2013-07-21 17:09 fangguo 阅读(156) 评论(0) 推荐(0) 编辑
摘要: 思路:将所有强连通分支找出来,并进行缩点,然后找其中所有出度为0的连通分支,就是题目要求的。#include#include#include#include#include#define Maxn 5100#define Maxm Maxn*100#define inf 0x7fffffffusing namespace std;int index[Maxn],vi[Maxn],stack[Maxn],dfn[Maxn],low[Maxn],e,n,lab,top,num,list,mark[Maxn],degree[Maxn],be[Maxn];struct Edge{ int fro... 阅读全文
posted @ 2013-07-20 16:35 fangguo 阅读(217) 评论(0) 推荐(0) 编辑
摘要: 思路:建图时,分别建正向图edge和转置图T。用正向图edge来DFS,找出第一个被发现的强连通分支(如果该图存在题目要求的点,那么一定就是第一个被发现的)。然后用spfa跑转置图T,判断被发现的点是否可以到达所有点,如可以,就把该连通同的点数输出。否则输出0 。#include#include#include#include#include#define Maxn 10100#define Maxm Maxn*10#define inf 0x7fffffffusing namespace std;int index[Maxn],vi[Maxn],stack[Maxn],dfn[Maxn],l 阅读全文
posted @ 2013-07-20 15:05 fangguo 阅读(173) 评论(0) 推荐(0) 编辑
摘要: 思路与poj3177一模一样。#include#include#include#include#include#define Maxn 1010#define Maxm Maxn*Maxn#define inf 0x7fffffffusing namespace std;int dfn[Maxn],low[Maxn],degree[Maxn],e,n,lab,index[Maxn];struct Edge{ int to,from,next,v;}edge[Maxm];void init(){ memset(dfn,0,sizeof(dfn)); memset(low,0,s... 阅读全文
posted @ 2013-07-20 10:04 fangguo 阅读(166) 评论(0) 推荐(0) 编辑
摘要: 思路:dfs求出所有点的low值,然后对每个连通分量进行缩点,可以通过low来进行缩点。虽然在同一连通分量里可能存在不同的low值,但这并不影响缩点。将每个连通分量缩为一个点后,只要求出这个缩点后的树上的叶子节点个数就行了。结果为(leaf+1)/2。#include#include#include#include#include#include#define Maxn 1010#define Maxm Maxn*10using namespace std;int index[Maxn],degree[Maxn],dfn[Maxn],low[Maxn],e,n,lab=0,num,visit[ 阅读全文
posted @ 2013-07-20 10:01 fangguo 阅读(169) 评论(0) 推荐(0) 编辑
摘要: 思路:对于该图,直接用建图貌似没法解,所以也很容易想到建补图,这样存在边的两个点就能再圆桌上做一起。也就将问题转化为对双连通分量中是否存在奇圈了。我们将每次查询的边保存在stack中,当遇到关键点的时候,stack里面保存的就是一个连通分量。在该连通分量中进行深搜,每次标记一个与父节点相反的颜色。当某次子节点与父节点颜色相同,那么就存在奇圈,且该连通分量中所有的点都在奇圈中。将这些点标记,最后进行遍历就行了。引用discuss里的话:一个块若无法做二分图染色,势必存在一个长度为奇数的环任找一个奇环C,则对于任意一个非环上的点A,一定有两条不相交的路,连向这个奇环,交奇环于两个不同的点P、Q(否 阅读全文
posted @ 2013-07-19 20:50 fangguo 阅读(266) 评论(0) 推荐(0) 编辑
摘要: 思路:当a,b的根节点find(a)与find(b)不同时,就直接将这两个数连接起来。由于每个树的根节点的kind值一定为0,所以,对于a,b的kind值相同,我们就讲其中一个根的kind值变为1,当下次再遍历该节点的时候,a与b的kind值就会变得不同。如果a,b的kind值相同,那么就不用变。看代码:#include#include#include#include#define Maxn 20010using namespace std;int set[Maxn],kind[Maxn];int find(int x){ if(x!=set[x]) { int te... 阅读全文
posted @ 2013-07-19 17:24 fangguo 阅读(156) 评论(0) 推荐(0) 编辑
摘要: 思路:对于所有节点,每次找的子树,key[root]++;输出时,对于根节点就输出key[root],对于其它节点i,输出key[i]+1;#include#include#include#include#include#define Maxn 1010#define Maxm Maxn*10#define inf 0x7fffffffusing namespace std;int dfn[Maxn],low[Maxn],index[Maxn],vi[Maxn],n,e,lab,key[Maxn],flag=0;struct Edge{ int to,next,val,from;}edg... 阅读全文
posted @ 2013-07-19 15:25 fangguo 阅读(150) 评论(0) 推荐(0) 编辑
摘要: 看完题目第一遍,感觉很简单。当写完程序跑测试用例的时候,发现第二个总是过不了,然后好好研究了一下测试用例,才知道原来不是程序有问题,而是我的建图方式错了。对于这些无序的点,如果高的在右边,不等式是dis[tall]-dis[short]#include#include#include#include#define Maxn 1010#define inf 0x7fffffff#define Maxm Maxn*Maxnusing namespace std;int dis[Maxn],index[Maxn],vi[Maxn],e,n;struct Edge{ int to,next,va... 阅读全文
posted @ 2013-07-19 11:11 fangguo 阅读(219) 评论(0) 推荐(0) 编辑