网络流
【最大流—EK】
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int INF=1e9;
//链式前向星存图已经基本忘完辽qaq所以还是EK搞一搞吧
const int maxn = 10001;
queue<int> q;
int n,m;
int x,y,s,t;
int g[maxn][maxn],pre[maxn],flow[maxn],maxflow;
//g邻接矩阵存图,pre增广路径中每个点的前驱,flow源点到这个点的流量 ,maxflow最大流
int bfs(int s,int t)
{
while (!q.empty()) q.pop();//初始化,清空队列//前驱全部标记为-1
for (int i=1; i<=n; i++) pre[i]=-1;
pre[s]=0;//pre数组在这里起到了两个作用,一个是标记当前点有没有被访问过,一个是记录前驱(没有被访问过的结点肯定没有前驱喵)
q.push(s);
flow[s]=INF;
while (!q.empty())
{
int v=q.front();
q.pop();
if (v==t) break;
for (int i=1; i<=n; i++)
//EK一次只找一个增广路
if (g[v][i]>0 && pre[i]==-1)
{
pre[i]=v;
flow[i]=min(flow[v],g[v][i]);
q.push(i);
}
}
if (pre[t]==-1) return -1;
else return flow[t];
}
//increase为增广的流量
void EK(int s,int t)
{
int increase=0;
while ((increase=bfs(s,t))!=-1)//这里的括号加错了!Tle
{//迭代
int k=t;
while (k!=s)
{
int last=pre[k];//从后往前找路径
g[last][k]-=increase;//正向边-流量
g[k][last]+=increase;//反向边加流量
k=last;//继续往前迭代
}
maxflow+=increase;//最大流继续加流量
}
}
int main()
{
scanf("%d%d%d%d",&n,&m,&s,&t);
for (int i=1; i<=m; i++)
{
int z;
scanf("%d%d%d",&x,&y,&z);
g[x][y]+=z;//此处不可直接输入,要+= //考虑重边
}
EK(s,t);
printf("%d",maxflow);
return 0;
}
【最大流—dicnic】
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
const int MAXE = 100000000;
const int MAXV = 100000;
const int inf = 1e9;
struct node {
int from, to, val;
int nxt;
};
node edge[MAXE];
int head[MAXV];
int n, m, cnt, s, t;
void add_edge(int u, int v, int w) {
edge[cnt].from = u, edge[cnt].to = v, edge[cnt].val = w;
edge[cnt].nxt = head[u], head[u] = cnt++;
edge[cnt].from = v, edge[cnt].to = u, edge[cnt].val = 0;
edge[cnt].nxt = head[v], head[v] = cnt++;
}
int deep[MAXV];
bool bfs(int s,int t)
{
memset(deep, 0, sizeof(deep));
queue<int> q;
q.push(s);
deep[s] = 1;
while (!q.empty())
{
int tmp = q.front();
q.pop();
for (int i = head[tmp]; i != -1; i = edge[i].nxt)
{
int v = edge[i].to;
if (deep[v] || edge[i].val <= 0) continue;
deep[v] = deep[tmp] + 1;
q.push(v);
}
}
return deep[t];
}
int dfs(int u, int flow)
{
//flow为到达终点最多能增广的值
if (u == t) return flow;
int maxflow = 0;
//u点的最大增广量
for (int i = head[u]; i != -1 && maxflow < flow; i = edge[i].nxt)
{
int v = edge[i].to;
if (deep[v] != deep[u] + 1) continue;
if (!edge[i].val) continue;
int tadd = dfs(v, min(edge[i].val, flow - maxflow));
edge[i].val -= tadd;
edge[i ^ 1].val += tadd;
maxflow += tadd;
}
return maxflow;
}
long long int dinic()
{
long long int ans = 0;
while (bfs(s,t))
ans += dfs(s, inf);
return ans;
}
int main()
{
memset(head, -1, sizeof head);
scanf("%d%d%d%d", &n, &m, &s, &t);
int x, y, z;
for (int i = 0; i < m; ++i) {
scanf("%d%d%d", &x, &y, &z);
add_edge(x, y, z);
}
printf("%lld", dinic());
return 0;
}
字符串-KMP
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 1000009;
char ans[maxn];
char word[maxn];
int next[maxn];
void get_next(int len)
{
int j = 0;
next[0] = next[1] = 0;
for(int i =2;i<=len;i++)
{
j = next[i - 1];
while(j && word[i] != word[j+1]) j = next[j];
if(word[i] == word[j+1]) next[i] = j+1;
else next[i] = 0;
}
}
void KMP(int ans_len,int word_len)
{
int j = 0;
for(int i = 1;i <= ans_len;i++)
{
while(j && ans[i] != word[j+1]) j = next[j];
if(ans[i] == word[j+1]) j++;
if(j == word_len) j = next[j],printf("%d\n",i-word_len+1);
}
/*for(int j = 1;j <= word_len ; j++)
{
printf("%d ",next[j]);
}*/
}
int main()
{
scanf("%s",ans+1);
scanf("%s",word+1);
int word_len = strlen(word+1);
int ans_len = strlen(ans+1);
get_next(word_len);
KMP(ans_len,word_len);
return 0;
}
线段树—rmq
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 1000009;
int n,m,dat[4*maxn];
const int inf = 1000000009;
int ans[maxn];
int temp ;
void init(int &n)
{
int N = n;
while(n < N) n*=2;
for(int i=0;i < 2*n -1;i++) dat[i] = inf;
}
void update(int k,int a)
{
k += n-1;
dat[k] = a;
while(k > 0)
{
k = (k-1)/2;
dat[k] = min(dat[2*k+1],dat[2*k+2]);
}
}
int query(int a,int b,int k,int l,int r)
{
if(a >= r||b<=l) return inf;
if(a<=l && r<= b) return dat[k];
else
{
int vl = query(a,b,2*k+1,l,(l+r)/2);
int vr = query(a,b,2*k+2,(l+r)/2,r);
return min(vl,vr);
}
}
void slove()
{
for(int i=0;i<=temp-m;i++)
{
ans[i] = query(i,i+m,0,0,n);
printf("%d\n",ans[i]);
}
}
int main()
{
scanf("%d%d",&n,&m);
temp = n;
n = 1;
while(n < temp) n *= 2;
//printf("n:%d\n",n);
for(int i=0;i < 2*n -1;i++) dat[i] = inf;
for(int i=0;i<n;i++)
{
if(i<temp)
{
int x;
scanf("%d",&x);
update(i,x);
}
else
{
update(i,inf);
}
}
/*printf("---------------\n");
for(int i = 0;i<2*n-1;i++) printf("%d, ",dat[i]);
printf("\n---------------\n");*/
slove();
//printf("!%d\n",query(0,m,0,0,n));
return 0;
}