复习计划

 明天要考试啦今天就扫一扫以前的模板吧

 感觉有点方

字符串

1.AC自动机

cogs1913裸题

#include <bits/stdc++.h>

using namespace std;

char str[12][100], s[10000010];
int n, cnt;
int t[1000][26], fail[1000];
int is[1000];

struct Edge {
	int to, nxt;
}edge[10010];
int h[1000], edges;
void addedge(int u, int v) {
	++ edges;
	edge[edges].to = v;
	edge[edges].nxt = h[u];
	h[u] = edges;
}

void insert(char* str, int pos) {
	int nw = 0, n = strlen(str+1);
	for(int i = 1; i <= n; ++ i) {
		int c = str[i]-'a';
		if(t[nw][c] == -1) t[nw][c] = ++ cnt, nw = cnt;
		else nw = t[nw][c];
	} is[nw] = pos;
}

int que[1000], head, tail;

void buildfail() {
	for(int i = 0; i < 26; ++ i)
		if(t[0][i] == -1) t[0][i] = 0;
		else que[tail ++] = t[0][i], fail[t[0][i]] = 0;
	while(head != tail) {
		int u = que[head ++];
		for(int i = 0; i < 26; ++ i) {
			if(t[u][i] == -1) t[u][i] = t[fail[u]][i];
			else fail[t[u][i]] = t[fail[u]][i], que[tail ++] = t[u][i];
		}
	}
	
	for(int i = 1; i <= cnt; ++ i)
		addedge(fail[i], i);
}

int dfs_clock, dfn[1000];
bool vis[1000];
void dfs(int u) {
	dfn[++ dfs_clock] = u;
	vis[u] = true;
	for(int i = h[u]; i; i = edge[i].nxt) {
		int v = edge[i].to;
		if(!vis[v]) dfs(v);
	}
}

int num[1000], ans[12];

int main() {
	freopen("ACautomata.in","r",stdin);
	freopen("ACautomata.out","w",stdout);
	scanf("%d", &n);
	memset(t, -1, sizeof t);
	for(int i = 1; i <= n; ++ i) {
		scanf("%s", str[i]+1);
		insert(str[i], i);
	}
	
	buildfail();
	dfs(0);
	scanf("%s", s+1);
	int len = strlen(s+1), nw = 0;
	for(int i = 1; i <= len; ++ i) {
		nw = t[nw][s[i]-'a'];
		num[nw] ++;
	}
	
	for(int i = dfs_clock; i; -- i)
		num[fail[dfn[i]]] += num[dfn[i]];

	for(int i = 1; i <= cnt; ++ i)
		if(is[i]) ans[is[i]] = num[i];
	for(int i = 1; i <= n; ++ i)
		printf("%s %d\n", str[i]+1, ans[i]);
	return 0;
} 

2.后缀自动机

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#define maxn 100010
using namespace std;

char s[maxn], c[maxn];
struct Node {
	int len, link, nxt[26];
} st[maxn << 1];
int size, root, last;

void init() {
	size = root = last = 0;
	st[root].link = -1;
	st[root].len = 0;
}

void Extend(char ch) {
	int cur = ++ size;
	int p, c = ch-'a';
	st[cur].len = st[last].len+1;
	for(p = last; ~p && st[p].nxt[c] == 0; p = st[p].link)
		st[p].nxt[c] = cur;
	if(p == -1)
		st[cur].link = root;
	else {
		int q = st[p].nxt[c];
		if(st[p].len+1 == st[q].len)
			st[cur].link = q;
		else {
			int clone = ++ size;
			st[clone] = st[q];
			st[clone].len = st[p].len+1;
			for(; ~p && st[p].nxt[c] == q; p = st[p].link)
				st[p].nxt[c] = clone;
			st[q].link = st[cur].link = clone;
		}
	} last = cur;
}

int main() {
	scanf("%s%s", s+1, c+1);
	int n = strlen(s+1), m = strlen(c+1);
	init();
	for(int i = 1; i <= n; ++ i)
		Extend(s[i]);
	int now = root, step = 0, ans = 0;
	for(int i = 1; i <= m; ++ i) {
		int p = c[i]-'a';
		if(st[now].nxt[p]) now = st[now].nxt[p], step ++;
		else {
			for(; ~now && !st[now].nxt[p]; now = st[now].link);
			if(now == -1) now = root, step = 0;
			else {
				step = st[now].len+1;
				now = st[now].nxt[p];
			}
		}
		ans = max(ans, step);
	}
	
	printf("%d\n", ans);
	return 0;
} 

  

  

图论

1.二分图最大匹配

BZOJ1191 超级英雄Hero

g[], vis[], tim

#include<bits/stdc++.h>
#define maxn 10010
using namespace std;

int n, m;

struct Edge { int to, nxt; }edge[100010];
int h[maxn], cnt;
void addedge(int u, int v) {
	++ cnt;
	edge[cnt].to = v;
	edge[cnt].nxt = h[u];
	h[u] = cnt;
}

int g[maxn], vis[maxn], tim;


bool find(int u) {
	vis[u] = tim;
	for(int i = h[u]; i; i = edge[i].nxt) {
		int v = edge[i].to;
		if(vis[v] == tim) continue;
		vis[v] = tim;
		if(g[v] == 0 || find(g[v])) {
			g[v] = u;
			g[u] = v;
			return true;	
		}
	} return false;
}

int main() {
	scanf("%d%d", &n, &m);
	int u, v;
	for(int i = 1; i <= m; ++ i) {
		scanf("%d%d", &u, &v);
		u += m+1;
		v += m+1;
		addedge(i, u);
		addedge(u, i);
		addedge(i, v);
		addedge(v, i);
	}

	int ans = 0;
	for(int i = 1; i <= m; ++ i) 
		if(!g[i]) {
			++ tim;
			if(find(i)) ans ++;
			else break;	
		}
	printf("%d\n", ans);
	return 0;
}

 2.强联通分量

cogs908 校园网

low[], pre[], sccno[], dfs_clock, scc_cnt

注意区分强联通分量的编号和具体点的编号

#include<bits/stdc++.h>
#define maxn 105
using namespace std;

int n;

struct Edge {
	int to, nxt;
}edge[maxn*maxn*2];
int h[maxn], cnt;
void addedge(int u, int v) {
	++ cnt;
	edge[cnt].to = v;
	edge[cnt].nxt = h[u];
	h[u] = cnt;
}

stack<int> sta;
int sccno[maxn], low[maxn], pre[maxn];
int dfs_clock, scc_cnt;

void Tarjan(int u) {
	sta.push(u);
	pre[u] = low[u] = ++ dfs_clock;
	for(int i = h[u]; i; i = edge[i].nxt) {
		int v = edge[i].to;
		if(!pre[v]) Tarjan(v), low[u] = min(low[u], low[v]);
		else if(!sccno[v]) low[u] = min(low[u], pre[v]);
	}
	
	if(low[u] == pre[u]) {
		++ scc_cnt;
		for( ; ;) {
			int v = sta.top();
			sta.pop();
			sccno[v] = scc_cnt;
			if(v == u) break;
		}
	}
}

int in[maxn], out[maxn];

int main() {
	freopen("schlnet.in","r",stdin);
	freopen("schlnet.out","w",stdout);
	scanf("%d", &n);
	int x;
	for(int i = 1; i <= n; ++ i) 
		while(scanf("%d", &x) && x) 
			addedge(i, x);
	
	for(int i = 1; i <= n; ++ i)
		if(!sccno[i]) Tarjan(i);
	for(int u = 1; u <= n; ++ u) {
		for(int i = h[u]; i; i = edge[i].nxt) {
			int v = edge[i].to;
			if(sccno[u] != sccno[v])
				++ in[sccno[v]], ++ out[sccno[u]];
		}
	}
	
	if(scc_cnt == 1) {
		printf("1\n0\n");
		return 0;
	}
	
	int ans1 = 0, ans2 = 0;
	for(int i = 1; i <= scc_cnt; ++ i) {
		if(!in[i]) ++ ans1;
		if(!out[i]) ++ ans2;
	}
	printf("%d\n%d\n", ans1, max(ans1, ans2));
	return 0;
}

3.最大流

cogs草地排水

#include <bits/stdc++.h>

using namespace std;
int n, m, S, T;
struct Edge {
	int to, nxt, w;
}edge[10100];
int h[500], cnt;
void addedge(int u, int v, int w) {
	++ cnt;
	edge[cnt].to = v;
	edge[cnt].nxt = h[u];
	edge[cnt].w = w;
	h[u] = cnt;
	swap(u, v), w = 0;
	++ cnt;
	edge[cnt].to = v;
	edge[cnt].nxt = h[u];
	edge[cnt].w = w;
	h[u] = cnt;
}

const int inf = 0x7fffffff;

int que[500], d[500];
bool bfs() {
	int head = 0, tail = 0;
	memset(d, -1, sizeof d);
	d[S] = 0;
	que[tail ++] = S;
	while(head != tail) {
		int u = que[head ++];
		for(int i = h[u]; i; i = edge[i].nxt) {
			if(!edge[i].w) continue;
			int v = edge[i].to;
			if(d[v] == -1) {
				d[v] = d[u]+1;
				que[tail ++] = v;
			}
		}
	} return d[T] != -1;
}

int dfs(int x, int a) {
	if(x == T || a == 0) return a;
	int used = 0, f;
	for(int i = h[x]; i; i = edge[i].nxt) {
		int v = edge[i].to;
		if(d[v] == d[x]+1) {
			f = dfs(v, min(a-used, edge[i].w));
			edge[i].w -= f;
			edge[i^1].w += f;
			used += f;
			if(a == used) return a;
		}
	}
	if(used == 0) d[x] = -1;
	return used;
}

int Dinic() {
	int ret = 0;
	while(bfs())
		ret += dfs(S, inf);
	return ret;
}

int main() {
	scanf("%d%d", &m, &n);
	cnt = 1;
	S = 1, T = n;
	int u, v, w;
	for(int i = 1; i <= m; ++ i) {
		scanf("%d%d%d", &u, &v, &w);
		addedge(u, v, w);
	}
	
	printf("%d\n", Dinic());
	return 0;
}

  

4.费用流

#include <bits/stdc++.h>
#define maxn 5000
using namespace std;

int n, p, s;
int a[maxn], b[maxn];

struct Edge {
	int to, nxt, w, dis;
}edge[500010];
int h[maxn], cnt, S, T;
void addedge(int u, int v, int w, int dis) {
	++ cnt;
	edge[cnt].w = w;
	edge[cnt].to = v;
	edge[cnt].dis = dis;
	edge[cnt].nxt = h[u];
	h[u] = cnt;
	swap(u, v), w = 0, dis = -dis;
	++ cnt;
	edge[cnt].w = w;
	edge[cnt].to = v;
	edge[cnt].dis = dis;
	edge[cnt].nxt = h[u];
	h[u] = cnt;
}

#define A n+1
#define B n+2
const int inf = 0x7fffffff/2;

int ans;
int dis[maxn], from[maxn];
bool vis[maxn];
queue<int> Q;
bool Spfa() {
	for(int i = S; i <= T; ++ i) 
		dis[i] = inf;
	dis[S] = 0;
	int head = 0, tail = 0;
	Q.push(S);
	while(!Q.empty()) {
		int u = Q.front(); Q.pop(); vis[u] = false;
		for(int i = h[u]; i; i = edge[i].nxt) {
			if(edge[i].w) {
				int v = edge[i].to;
				if(dis[v] > dis[u] + edge[i].dis) {
					dis[v] = dis[u] + edge[i].dis;
					from[v] = i;
					if(!vis[v]) {
						vis[v] = true;
						Q.push(v);
					}
				}
			}
		}
	}
	int x = inf;
	for(int i = from[T]; i; i = from[edge[i^1].to])
		x = min(x, edge[i].w);
	for(int i = from[T]; i; i = from[edge[i^1].to])
		ans += x*edge[i].dis, edge[i].w -= x, edge[i^1].w += x;
	return dis[T] < inf;
}

vector<int> G;

int main() {
	cnt = 1;
	scanf("%d%d%d", &n, &p, &s);
	for(int i = 1; i <= n; ++ i)
		scanf("%d", &a[i]);
	for(int i = 1; i <= n; ++ i)
		scanf("%d", &b[i]);
	
	S = 0, T = n+3;
	for(int i = 1; i <= n; ++ i) {
		addedge(S, i, 1, 0);
		addedge(i, A, 1, -a[i]);
		addedge(i, B, 1, -b[i]);
	}
	addedge(A, T, p, 0);
	addedge(B, T, s, 0);
	while(Spfa());
	printf("%d\n", -ans); 
	for(int i = h[A]; i; i = edge[i].nxt) 
		if(edge[i].w == 1) G.push_back(edge[i].to);
	sort(G.begin(), G.end());
	for(int i = 0; i < G.size(); ++ i)
		printf("%d ", G[i]);
	printf("\n");
	G.clear();
	for(int i = h[B]; i; i = edge[i].nxt) 
		if(edge[i].w == 1) G.push_back(edge[i].to);
	sort(G.begin(), G.end());
	for(int i = 0; i < G.size(); ++ i)
		printf("%d ", G[i]);
	return 0;
}

 5.KM算法

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#define maxn 305
using namespace std;

int n;
int G[maxn][maxn];
int Cx[maxn], Cy[maxn], linky[maxn], slack[maxn];
bool visx[maxn], visy[maxn];

bool dfs(int u) {
	visx[u] = true;
	for(int v = 1; v <= n; ++ v) {
		if(visy[v]) continue;
		int diffenerce = Cx[u]+Cy[v]-G[u][v];
		if(diffenerce == 0) {
			visy[v] = true;
			if(linky[v] == 0 || dfs(linky[v])) {
				linky[v] = u;
				return true;
			}
		}
		else slack[v] = min(slack[v], diffenerce);
	}
	return false;
}

int KM() {
	memset(Cx, 0, sizeof Cx);
	memset(Cy, 0, sizeof Cy);
	memset(linky, 0, sizeof linky);
	for(int i = 1; i <= n; ++ i) {
		Cx[i] = G[i][1];
		for(int j = 2; j <= n; ++ j)
			Cx[i] = max(Cx[i], G[i][j]);
	}

	for(int i = 1; i <= n; ++ i) {
		memset(slack, 0x7f, sizeof slack);
		while(true) {
			memset(visx, 0, sizeof visx);
			memset(visy, 0, sizeof visy);
			if(dfs(i)) break;
			int d = 0x7fffffff;
			for(int j = 1; j <= n; ++ j)
				if(!visy[j]) d = min(d, slack[j]);
			for(int j = 1; j <= n; ++ j) {
				if(visx[j]) Cx[j] -= d;
				if(visy[j]) Cy[j] += d;
				else slack[j] -= d;
			}
		}
	}

	int res = 0;
	for(int i = 1; i <= n; ++ i) 
		res += G[linky[i]][i];
	return res;
}


int main() {
	while(scanf("%d", &n) != EOF) {
		for(int i = 1; i <= n; ++ i)
			for(int j = 1; j <= n; ++ j)
				scanf("%d", &G[i][j]);
		printf("%d\n", KM());
	} 
	return 0;
}

 

 

因自己的小错误 

然后考试就炸了。。罚时超多

比较印象深刻的是考了trie,字符串处理,凸包(想着复习计算几何但是没有复习但是还是写出来了!),最小生成树等等

比较基础吧,主要是读英文题有点费劲

第25名不知道能不能进实验班

posted @ 2017-09-06 19:36  _Horizon  阅读(366)  评论(0编辑  收藏  举报