07 2013 档案
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1534思路:设s[i]表示工作i的开始时间,v[i]表示需要工作的时间,则完成时间为s[i]+v[i].于是可以列出下列不等式:FAS a b :b开始之后a结束,s[a]+v[a]>=s[b];FAF a b :b结束之后a结束,s[a]+v[a]>=s[b]+v[b];ASF a b :b结束之后a开始,s[a]>=s[b]+v[b];ASA a b :b开始之后a开始,s[a]>=s[b];从而建图求最长路即可,需要注意的是一开始dist[]初始化为-inf.http:
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1531差分约束的题之前也碰到过,刚好最近正在进行图论专题的训练,就拿来做一做。①:对于差分不等式,a - b = c ,建一条 b 到 a 的权值为 c 的边,求的是最长路,得到的是最小值③:存在负环的话是无解。④:求不出最短路(dist[ ]没有得到更新)的话是任意解说明一下为什么存在负环就是无解?我们的目标是求不等式的解,而不等式的解正是超级源点到各点的最短距离,而如果存在负环的话,是无法求得最短距离的,从而也就无法求出不等式的解。回到本题,我们可以设s[i] = a[1] + a[2] + …
阅读全文
摘要:题目链接:http://poj.org/problem?id=3621思路:之前做过最小比率生成树,也是属于0/1整数划分问题,这次碰到这道最优比率环,很是熟悉,可惜精度没控制好,要不就是wa,要不就是tle,郁闷啊!实在是懒得码字,直接copy吧:题目的意思是:求一个环的{点权和}除以{边权和},使得那个环在所有环中{点权和}除以{边权和}最大。令在一个环里,点权为v[i],对应的边权为e[i], 即要求:∑(i=1,n)v[i]/∑(i=1,n)e[i]最大的环(n为环的点数), 设题目答案为ans, 即对于所有的环都有 ∑(i=1,n)(v[i])/∑(i=1,n)(e[i])=∑(i.
阅读全文
摘要:题目链接:http://poj.org/problem?id=3662思路:这题较多的有两种做法:方法1:二分枚举最大边长limit,如果图中的边大于limit,则将图中的边当作1,表示免费使用一次,否则就当作0,这样只需判断dist[n]与k的大小,然后继续二分边长就可了。方法2:bfs+优先队列,dp[i][j]表示到顶点i,免费使用了j条边的最小花费,于是对于下一个即将要选择的点,那么就有两种选择了,一种是免费使用这条边,另一种是不免费,则花费为q.cost=max(p.cost,w),不断进出队列更新即可。http://paste.ubuntu.com/5931748/
阅读全文
摘要:题目链接:http://poj.org/problem?id=3635思路:本题主要运用的还是贪心思想,由于要求st->ed的最小花费,那么每经过一个城市,能不加油就尽量不加油,用dp[i][j]表示在顶点i,剩余燃料为j是的最小花费,于是每走到一个城市,可以选择不加油,也可以选择加1,2,3...,个单位的油,然后用优先队列来保存每个状态,如果有更小的花费,就入队列,这样直到第一次到达终点,此时花费就是最小的了。http://paste.ubuntu.com/5931435/
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4628思路:首先把所有的回文找出来,如果当前状态为回文,则dp[state]=1,否则dp[state]=inf.然后就是枚举所有的状态:若当前状态为state,枚举子状态(substate=(substate-1)&state),则有dp[state]=min(dp[state],dp[substate^state]+dp[substate])(其中(substate^state)表示删除substate后的状态。最后就是要求dp[(1<<len)-1]了。http://pas
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4462思路:由于数据不大,可以直接将所有的状态表示出来,然后枚举,判断能否将方格全部覆盖。http://paste.ubuntu.com/5928952/
阅读全文
摘要:题目链接:http://poj.org/problem?id=3615思路:map[i][j]表示顶点i,j之间的最高的障碍物,于是题目要求的是最高障碍物的最小值,不就是min(map[i][j],max(map[i][k],map[k][j]))嘛.http://paste.ubuntu.com/5925170/
阅读全文
摘要:题目链接:http://poj.org/problem?id=3613思路:我们知道如果矩阵A表示经过1条边的方案数,那么A^N矩阵就代表这经过N条边的方案数,而本题中要求经过N条边的最短距离,于是我们可以把原来矩阵的乘法改成加法,这在08年国家队的一篇论文中有证明:《矩阵乘法在信息学中的应用》。至于怎么求A^N矩阵,二分即可。http://paste.ubuntu.com/5925042/
阅读全文
摘要:题目链接:http://poj.org/problem?id=3328思路:这道题花了我将近3个小时,结果发现是方向搞错了,orz,过了样例之后提交wa,然后换成优先队列就过了.其实题目意思很简单,就是说一个人从S点起跳,如果先前是左脚(右脚)着地,那么之后只能往某一个特定的区域跳,而经过仔细观察之后可以发现,这块区域可以统一来表示,这样的话就相当于是一个二维平面上的最短路了,只不过是多源多终点,然后我们用一个状态来标记当前的位置以及走的时间和跳的方向,由于使用了优先队列,则找到第一个终点就直接返回就行了。http://paste.ubuntu.com/5922030/
阅读全文
摘要:题目链接:http://poj.org/problem?id=3311思路:Floyd + 状态压缩DP 题意是有N个城市(1~N)和一个PIZZA店(0),要求一条回路,从0出发,又回到0,而且距离最短 (可重复走).首先不难想到用FLOYD先求出任意2点的距离dis[i][j] 。接着枚举所有状态,用11位二进制表示10个城市和pizza店,1表示经过,0表示没有经过 。定义状态DP(S,i)表示在S状态下,到达城市I的最优值 。接着状态转移方程:DP(S,i) = min{DP(S^(1<<i-1),k) + dis[k][i],DP(S,i)},器重S^(1<<
阅读全文
摘要:题目链接:http://poj.org/bbs?problem_id=3255思路:分别以源点1和终点N为源点,两次SPFA求得dist1[i](1到各点的最短距离)以及dist2[i](各点到N的最短距离),然后就是枚举边了,设某一条边的两端为u,v,权值为w,则dist1[u]+w+dist2[v]即为1->N的一条路径,在所有的路径中找出次短的即可。http://paste.ubuntu.com/5920862/
阅读全文
摘要:题目链接:http://poj.org/problem?id=3072一涉及稍微计算几何方面的东西就要做好久,一开始先用SPFA写的,可能是由于松弛次数过多导致精度损失,郁闷了好久,然后改成Dijkstra就没什么问题了。http://paste.ubuntu.com/5920764/
阅读全文
摘要:题目链接:http://poj.org/problem?id=2449思路:我们可以定义g[x]为源点到当前点的距离,h[x]为当前点到目标节点的最短距离,显然有h[x]<=h*[x](h*[x]定义为当前点到目标节点的实际距离),至于怎么求的h[x],即图中任何节点到目标节点的最短距离,这里我们可以建反图,以目标节点为源点一次spfa就可以求得各点到目标节点的最短距离了。然后就是A*求第k短路了,f[x]=g[x]+h[x],每次将最小的f[x]出队列,直到目标节点被扩展了k次,则求得了第k短路,这里还有一个优化,即如果某一个节点扩展次数大于k次,就没必要在继续扩展了。http://p
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4618昨天多校的一道题,说多了都是泪啊,为了一道图论题,磨了那么久,结果是别的题都没看,没办法,补呗。思路:题目数据不大,直接按矩阵大小枚举,如果存在n阶矩阵为回文矩阵,则直接break枚举n+1阶矩阵。http://paste.ubuntu.com/5913255/
阅读全文
摘要:题目链接:http://poj.org/problem?id=1797思路:题目意思很简单,n个顶点,m条路,每条路上都有最大载重限制,问1->n最大载重量。其实就是一最短路的变形,定义weight[i]表示源点到顶点i的最大载重量,初始化为0,之后不断去更新就行了。 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 using namespace std; 8 #define MAXN 1010 9 #define inf 1 >map;20 21 int SPFA()22 {23 memset
阅读全文
摘要:题目链接:http://poj.org/problem?id=1724思路:有限制的最短路,或者说是二维状态吧,在求最短路的时候记录一下花费即可。一开始用SPFA写的,900MS险过啊,然后改成Dijkstra+priority_queue,60MS,orz.SPFA: 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 using namespace std; 8 #define MAXN 104 9 #define inf 1Pair;11 12 struct Edge{13 int v,w,c;1...
阅读全文
摘要:题目链接:http://poj.org/problem?id=1511思路:题目意思很简单就是要求源点到各点的最短路之和,然后再求各点到源点的最短路之和,其实就是建两个图就ok了,其中一个建反图。1000000个点和1000000条边,一开始用SPFA+vector怎么都是TLE,然后换成邻接表就过了=.=。 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 using namespace std; 8 #define MAXN 1000100 9 #define inf 1LLQ;35 Q.push...
阅读全文
摘要:题目链接:http://poj.org/problem?id=1062思路:要求对于最短路上的点,不能出现等级之差大于m,于是我们可以枚举,假设酋长的等级为level,于是这个区间范围[level-m,level],[level-m+i,level+i],......,[level,level+m]都是可行的,对于枚举的每个区间范围,做一次SPFA即可,最终结果取最小值即可。 1 #include 2 #include 3 #include 4 #include 5 #include 6 using namespace std; 7 #define MAXN 111 8 #define inf
阅读全文
摘要:题目链接:http://poj.org/problem?id=3159思路:题目意思很简单,都与给定的条件dist[b]-dist[a]b直接连边,边权值为c,从而题目转化为图上求1->n的最短路,看了一下数据,30000个点,150000条边,果断用Dijkstra+priority_queue,1300MS+险过,orz. 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 using namespace std; 8 #define MAXN 30030 9 #define inf 1Pair;11
阅读全文
摘要:题目链接:http://poj.org/problem?id=3114思路:题目要求很简单,就是求两点之间的花费的最短时间,不过有一个要求:如果这两个city属于同一个国家,则花费时间为0。如何判断一个是属于同一个国家呢?就要缩点了,这样属于同一个强连通分量的点就是属于同一个国家了。然后就是SPFA求最短路。 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 using namespace std; 9 #define MAXN 55510 #define inf 1 >map;2
阅读全文
摘要:题目链接:http://poj.org/problem?id=2762思路:首先当然是要缩点建新图,由于题目要求是从u->v或从v->u连通,显然是要求单连通了,也就是要求一条长链了,最后只需判断链长是否等于新图顶点个数即可,至于如何求一条链长,直接dfs即可,注意点就是dfs是要从入度为0的顶点开始。 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 using namespace std; 8 #define MAXN 1010 9 10 int low[MAXN],dfn[MAXN],col
阅读全文
摘要:题目链接:http://poj.org/problem?id=3352思路:可以求出所有的桥,把桥删掉。然后把所有的连通分支求出来,显然这些连通分支就是原图中的双连通分支。把它们缩成点,然后添上刚才删去的桥,就构成了一棵树。在树上添边使得树变成一个双连通分支即可,这里我们可以直接统计缩点后的叶子节点个数即可,从而要加的边数即为(叶子节点个数+1)/2. 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 using namespace std; 9 #define MAXN 222210
阅读全文
摘要:题目链接:http://poj.org/problem?id=3228思路:增设一个超级源点和一个超级汇点,源点与每一个gold相连,容量为gold数量,汇点与仓库相连,容量为仓库的容量,然后就是二分最小的最大相邻距离,跑最大流验证即可。最大流用的是别人的Dinic模版。 1 #include 2 #include 3 #include 4 #include 5 #include 6 using namespace std; 7 #define MAXN 222 8 #define inf 1 q; 30 while(!q.empty()) 31 q.p...
阅读全文
摘要:题目链接:http://poj.org/problem?id=3522思路:题目要求最小生成树中最大边与最小边的最小差值,由于数据不是很大,我们可以枚举最小生成树的最小边,然后kruskal求最小生成树,直到不能生成生成树为止,然后取最小的差值即可。 1 #include 2 #include 3 #include 4 #include 5 using namespace std; 6 #define MAXN 111 7 #define inf 1<<30 8 9 struct Edge{10 int u,v;11 int len;12 }edge[MAXN*MAXN];1...
阅读全文
摘要:题目链接:http://poj.org/problem?id=2349思路:由于有S个专门的通道,我们可以先求一次最小生成树,然后对于最小生成树上的边从大到小排序,前S-1条边用S-1个卫星通道连接,那么第S大条边就是我们要找的最小的D了。 1 #include 2 #include 3 #include 4 #include 5 #include 6 using namespace std; 7 #define MAXN 555 8 #define inf 1LLq;29 }30 31 double Prim(int u0)32 {33 int cnt=0;34 memset...
阅读全文
摘要:题目链接:http://poj.org/problem?id=1733思路:这题一看就想到要用并查集做了,不过一看数据这么大,感觉有点棘手,其实,我们仔细一想可以发现,我们需要记录的是出现过的节点到根节点的1个奇偶性,这与区间端点的大小并没有关系,于是想到我们可以用map映射即可,这样就解决了大数据了。此外,如果0表示出现偶数个1,1表示出现奇数个1,然后就是向量偏移关系了(http://www.cnblogs.com/wally/archive/2013/06/10/3130527.html). 1 #include 2 #include 3 #include 4 #include 5 #i
阅读全文
摘要:题目链接:http://poj.org/problem?id=3468思路:如果直接去做,每次都更新到叶子节点,那必然会TLE,我们可以采用lazy的思想:没必要每次更新都更新到叶子节点,只要有一个合适的范围就用一个增量来记录它,当下一次询问时,如果这个范围正好合适询问的范围,就直接是这个节点的sum值加上这个区间长度*lnc,再加到总和上去,若这个节点的范围不适合所要查询的范围,那么就要查询它的子节点,这个时候再把增量传给她的子节点,并且清空父亲节点的增量,这样效率能大大提高。 1 #include 2 #include 3 #include 4 #include 5 using ...
阅读全文
摘要:题目链接:http://poj.org/problem?id=1182解题思路来自discuss:http://poj.org/showmessage?message_id=152847 1 #include 2 #include 3 #include 4 using namespace std; 5 #define MAXN 50050 6 int parent[MAXN]; 7 int kind[MAXN]; 8 int n,m,tag; 9 10 void Initiate()11 {12 for(int i=0;in||b>n||(tag==2&&a==b)){
阅读全文
摘要:题目链接:http://poj.org/problem?id=1703思路;个人觉得本质上还是和带权并查集一样的,只不过多了一个MOD操作,然后就是向量关系图稍微改动一下就变成种类并查集了,对于本题,我们可以用一个kind数组来表示是否属于同一类,其中kind[x]==0表示不是同一类,kind[x]==1表示属于同一类,这样我们就可以得到向量关系式了(若r1=Find(u),r2=Find(v),并且parent[r1]=r2,那么就有kind[v]+1==kind[u]+kind[r1])然后变形后对2取余就可以了,即kind[r1]=(kind[v]-kind[u]+1)%2,这是Uni
阅读全文

浙公网安备 33010602011771号