AC自动机: http://www.cppblog.com/mythit/archive/2009/04/21/80633.html
最大二分匹配模板 ZQUOJ 23124&&POJ 1469
#include<stdio.h>
#include<string.h>
int g[301][301],vis[301],match[301],count; //g表示两点间是否有边,vis标记二分图右边的点是否访问过,match保存匹配的点
int n,m; //n右边的点的个数,m左边的点的个数
int dfs(int v)
{
int i;
for(i=1;i<=n;i++) //遍历右边的顶点
{
if(!vis[i]&&g[v][i]) //没访问过且边<v,i>存在
{
vis[i]=1;
if(dfs(match[i])||!match[i])
{ //如果该点还未与其他点匹配,或还能找到其他点能与该点匹配的点match[i]进行匹配,即存在增广路
match[i]=v; //将i与v进行匹配
return 1;
}
}
}
return 0;
}
void max_match()
{
int i;
memset(match,0,sizeof(match));
for(i=1;i<=m;i++) //遍历左边的顶点
{
memset(vis,0,sizeof(vis));
if(dfs(i)) //存在增广路径
count++;
}
}
int main()
{
int t,i,k,j,v;
scanf("%d",&t);
while(t--)
{
count=0;
memset(g,0,sizeof(g));
scanf("%d%d",&m,&n);
for(i=1;i<=m;i++)
{
scanf("%d",&k);
for(j=1;j<=k;j++)
{
scanf("%d",&v);
g[i][v]=1;
}
}
max_match(); //求最大二分匹配
if(count==m) //最大匹配数等于课程数
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
最大流模板 hdu 3549 (ISAP)
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#define N 505
#define inf 999999999
using namespace std;
int n,m,s,t,dis[N],pre[N],gap[N],flow[N][N];
struct edge
{
int v,w;
edge *next,*rev;
edge(){next=0;}
edge(int vv,int ww,edge *e){v=vv;w=ww;next=e;}
}*adj[N],*path[N],*e;
void insert(int u,int v,int w)
{
edge *p=new edge(v,w,adj[u]);
adj[u]=p;
edge *q=new edge(u,0,adj[v]);
adj[v]=q;
p->rev=q;
q->rev=p;
}
void bfs()
{
memset(dis,0x7f,sizeof(dis));
memset(gap,0,sizeof(gap));
queue<int> q;
dis[t]=0;
gap[0]=1;
q.push(t);
while(q.size())
{
int x=q.front();
q.pop();
for(e=adj[x];e;e=e->next)
{
if(e->rev->w==0||dis[e->v]<t)
continue;
dis[e->v]=dis[x]+1;
++gap[dis[e->v]];
q.push(e->v);
}
}
}
int ISAP()
{
memset(dis,0,sizeof(dis));
memset(gap,0,sizeof(gap));
//bfs();
int ans=0,u=s,d;
while(dis[s]<=t)
{
if(u==t)
{
int minflow=-1u>>1;
for(e=path[u];u!=s;e=path[u=pre[u]])
minflow=min(minflow,e->w);
for(e=path[u=t];u!=s;e=path[u=pre[u]])
{
e->w-=minflow;
e->rev->w+=minflow;
flow[pre[u]][u]+=minflow;
flow[u][pre[u]]-=minflow;
}
ans+=minflow;
}
for(e=adj[u];e;e=e->next)
if(e->w>0&&dis[u]==dis[e->v]+1)
break;
if(e)
{
pre[e->v]=u;
path[e->v]=e;
u=e->v;
}
else
{
if(--gap[dis[u]]==0)
break;
for(d=t,e=adj[u];e;e=e->next)
if(e->w>0)
d=min(d,dis[e->v]);
dis[u]=d+1;
++gap[dis[u]];
if(u!=s)
u=pre[u];
}
}
return ans;
}
int main()
{
int u,v,w;
int cas;
scanf("%d", &cas);
for(int k=1; k<=cas; k++)
{
scanf("%d %d", &n, &m);
memset(adj,0,sizeof(adj));
while(m--)
{
scanf("%d%d%d",&u,&v,&w);
insert(u,v,w);
//insert(v,u,w);//无向边
}
s=1;
t=n;
printf("Case %d: %d\n", k, ISAP());
}
}
Dinic:
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 5005
#define M 10005
#define inf 999999999
using namespace std;
int n,m,s,t,num,adj[N],dis[N],q[N];
struct edge
{
int v,w,pre;
}e[M];
void insert(int u,int v,int w)
{
e[num]=(edge){v,w,adj[u]};
adj[u]=num++;
e[num]=(edge){u,0,adj[v]};
adj[v]=num++;
}
int bfs()
{
int i,x,v,tail=0,head=0;
memset(dis,0,sizeof(dis));
dis[s]=1;
q[tail++]=s;
while(head<tail)
{
x=q[head++];
for(i=adj[x];i!=-1;i=e[i].pre)
if(e[i].w&&dis[v=e[i].v]==0)
{
dis[v]=dis[x]+1;
if(v==t)
return 1;
q[tail++]=v;
}
}
return 0;
}
int dfs(int s,int limit)
{
if(s==t)
return limit;
int i,v,tmp,cost=0;
for(i=adj[s];i!=-1;i=e[i].pre)
if(e[i].w&&dis[s]==dis[v=e[i].v]-1)
{
tmp=dfs(v,min(limit-cost,e[i].w));
if(tmp>0)
{
e[i].w-=tmp;
e[i^1].w+=tmp;
cost+=tmp;
if(limit==cost)
break;
}
else dis[v]=-1;
}
return cost;
}
int Dinic()
{
int ans=0;
while(bfs())
ans+=dfs(s,INT_MAX);
return ans;
}
int main ()
{
while(~scanf("%d%d",&m,&n))
{
int u,v,w;
memset(adj,-1,sizeof(adj));
num=0;
s=1;
t=n;
while(m--)
{
scanf("%d%d%d",&u,&v,&w);
insert(u,v,w);
}
printf("%d\n",Dinic());
}
}