摘要:
UVA_11991 先将所有值排个序,剩下的工作就比较好办了。#include<stdio.h>#include<string.h>#include<algorithm>#define MAXD 100010struct Point{ int id, v; bool operator < (const Point &t) const { if(v == t.v) return id < t.id; return v < t.v; }}p[MAXD];int N, M;void init(){ int i;... 阅读全文
摘要:
UVA_11988 实际上在插入模式下,敲一个字符的时候就相当于在前一个字符与前一个字符的后一个字符中间插入了一个字符,于是可以用链表模拟插入的过程,最后再沿链表将各个字符输出即可。#include<stdio.h>#include<string.h>#define MAXD 100010int L[MAXD], R[MAXD];char b[MAXD];void solve(){ int i, j, k; L[0] = R[0] = 0; for(i = 1; b[i]; i ++) { if(b[i] == '[') L[i] ... 阅读全文
摘要:
UVA_11987 操作2实际上相当于先把x删掉然后再和y合并,因此和普通的并查集相比只是多了一个删除某个点的操作。 对于删除操作,是不能随便改变原来树中p[]的指向的,比较容易能够举出反例。其实我们只是想在不影响其他元素的前提下把x删掉,但不如换个思路,将x这个点对它所在的集合的“影响”变为0。然后再新开一个节点表示x,这样就相当于把x从原来的集合中剥离出来了。因此相比原来的并查集,需要多一个id[x]数组表示点x现在的标号,有了上面的思路其余的操作就不难写出来了。#include#include#define MAXD 200010int N, M, p[MAXD], id[MAXD].. 阅读全文
摘要:
POJ_1419 好像有人2^N枚举才跑了125ms,所以如果加入简单的回溯的话,很容易跑得比较快。每次找到一个未染色的点的时候实际上有两种决策,要么保持这个点未染色的状态,要么就染成黑色并将其相邻的点染成白色。#include<stdio.h>#include<string.h>#include<algorithm>#define MAXD 110#define MAXM 20010#define INF 0x3f3f3f3fint N, M, first[MAXD], e, next[MAXM], v[MAXM], ANS;int col[MAXD], 阅读全文
摘要:
HDU_1941 这个题目说白了就是要删掉一些点,而且被删掉的点两两之间不能有边,留下的点两两之间必须有边,也就是构成一个完全图。 乍看起来是没啥思路的,不过大概有两条路子可以走,要么先考虑什么样的点一定会留下来,要么就先考虑什么样的点一定会被删掉。想想之后觉得第二条路子还可行一些,于是就开始想吧。 首先,孤立点是一定可以被删除的(这里以及后面的讨论默认最大度数的点的度数还算比较大),其次好像叶子节点也就是度数为1的点也可以删,再接着好像就不太好讨论了,不过前面这两类点是有共性的,也就是度数比较小,那么是不是先把度数比较小的点删掉就可以了? 不妨考虑一个度数比较小的点A和一个度数比较大... 阅读全文
摘要:
POJ_1986 没有太仔细看题意,dicuss里面说是查询树上两点间距离我就照办了,由于自己比较懒,一直没有学习和LCA相关的算法,所以只好复习一下前面写过的树链剖分和link-cut-tree了。View Code // 树链剖分#include<stdio.h>#include<string.h>#include<algorithm>#define MAXD 40010#define MAXM 80010int N, M, first[MAXD], e, v[MAXM], next[MAXM], w[MAXD], sum[4 * MAXD];int q 阅读全文
摘要:
POJ_2175 据说这个题目裸着做费用流会超时,不过实际上看完这个题目还是不难发现更好的思路的,因为题目又没要求要最优解,而是得到一个更优的解,那么如果在原图中能够找到一个总费用为负的回路的话,那么沿这个回路流量增加1就能够在不改变原始总流量的基础上使总费用变得更低,于是我们只要试图去找这样一个负圈就可以了。 如果用的SPFA的话,在一个点入队次数大于顶点数时就可以判断有负圈存在了,但这时刚刚入队的这个点却未必是负圈上的,但我们可以记录下来每个点被更新的前一个点,沿这个路径不停地回溯去找,直到发现找到的这个点在之间已经遇到过了,那么找到的这个点就一定是某个负圈上的点了。最后以这个点为基础.. 阅读全文
摘要:
SGU_185 这个题目被内存卡的严重头晕…… 其实思路还是满直观的,由于要两条路不相交,只要用网络流就行,再加上要两条最短路,那么就最小费用最大流,最后看两条路的费用和是不是最短路的两倍即可。但如果裸着这样写,由于无向边相当于两条有向边,不好意思,内存爆了……开小点吧,不好意思,RE了…… 晕……那还是换网络流写吧,这样少个记录费用的数组,可以先用dij从1开始搞遍最短路,再从N开始搞遍最短路,再遍历一遍所有边就知道哪条边是最短路上的边了,而且还知道了这条边的方向,那么根据这些最短路上的边组成的图做最大流就可以了,最后看总流量是不是为2。 当然敲到这里就发现了省内存的方法,只要先找到... 阅读全文
摘要:
UVALive_4271 这个题目一开始把这个项链描述地既详细又神奇,但是后来仔细想一下,实际上只要S和T之间能够存在一条回路,即从S出发走到T再走回来,中途不经过重复的边,那么这条回路就可以看成是满足题目描述的项链。 想到这就好办了,为了保证路不重复用网络流就可以了,接下来就虚拟出一个源点S',连一条S'到S的容量为2的边,其余原图上的边容量都看成1,然后看S'到T的最大流是不是2就可以了。#include<stdio.h>#include<string.h>#include<algorithm>#define MAXD 10010 阅读全文
摘要:
HDU_1960 如果把每条路线看成一个点,然后如果在任务i完成之后可以赶去做任务j就连一条i->j的有向边,这样我们就得到了一个有向无环图,而题目相当于想用最少的路径覆盖玩所有的顶点,这样就把问题转化成了二分图最小路径覆盖问题。#include<stdio.h>#include<string.h>#include<stdlib.h>#define MAXD 510#define MAXM 250010char b[10];int N, first[MAXD], e, next[MAXM], v[MAXM];int yM[MAXD], visy[MAX 阅读全文