您的位置:首页 > 其它

图论模板集合

2014-04-26 19:58 246 查看
二分图模板

匈牙利算法 时间复杂度O(n^3)

int n1,n2,k;

//n1,n2为二分图的顶点集,其中x∈n1,y∈n2
int map

,vis
,link
;
//link记录n2中的点y在n1中所匹配的x点的编号
int find(int x)
{
int i;
for(i=1;i<=n2;i++)
{
if(map[x][i]&&!vis[i])//x->i有边,且节点i未被搜索
{
vis[i]=1;//标记节点已被搜索
//如果i不属于前一个匹配M或被i匹配到的节点可以寻找到增广路
if(link[i]==0||find(link[i]))
{
link[i]=x;//更新
return 1;//匹配成功
}
}
}
return 0;
}


Hopcroft-Karp算法 时间复杂度O(n^0.5*e)

讲解参照


vector<int>ed[N];
int xlink[N],ylink[N];/*xlink[i]表示左集合顶点所匹配的右集合顶点序号,ylink[i]表示右集合i顶点匹配到的左集合顶点序号。*/
bool vis[N]; //寻找增广路的标记数组
int dx[N],dy[N];/*dx[i]表示左集合i顶点的距离编号,dy[i]表示右集合i顶点的距离编号*/

int dis,n;

void init()
{
memset(xlink,-1,sizeof(xlink));
memset(ylink,-1,sizeof(ylink));
}
int bfs()
{
memset(dx,-1,sizeof(dx));
memset(dy,-1,sizeof(dy));
int i;
queue<int>q;
dis = INF;
for(i = 1 ; i <= n;i++)
if(xlink[i]==-1)
{
q.push(i);
dx[i] = 0;
}
while(!q.empty())
{
int u = q.front(); q.pop();
if(dx[u]>dis) break;
for(i = 0 ;i < ed[u].size() ; i++)
{
int v = ed[u][i];
if(dy[v]==-1)
{
dy[v] = dx[u]+1;
if(ylink[v]==-1) dis = dy[v];
else
{
dx[ylink[v]] = dy[v]+1;
q.push(ylink[v]);
}
}
}
}
return dis!=INF;
}
int find(int u)
{
int i;
for(i = 0;i < ed[u].size() ; i++)
{
int v = ed[u][i];

if(vis[v]||dy[v]!=dx[u]+1) continue;
vis[v] = 1;
if(ylink[v] != -1&&dy[v]==dis) continue;
if(ylink[v]==-1||find(ylink[v])) {
ylink[v] = u;
xlink[u] = v;
return 1;
}
}
return 0;
}
int hk()
{
int ans = 0,i;
while(bfs())
{

memset(vis,0,sizeof(vis));
for(i = 1 ; i <= n ;i++)
{
if(xlink[i]==-1)
ans+=find(i);
}
}
return ans;
}


最大流模板

Edmonds-Karp算法 时间复杂度O(n*e^2)

int path
,flow
,gh

,st,en;
int bfs()
{
int i;
memset(path,-1,sizeof(path));
for(i = 1 ; i <= en ; i++)
flow[i] = INF;
queue<int>q;
q.push(1);
while(!q.empty())
{
int tk = q.front();
q.pop();
if(tk==en)
break;
for(i = 1 ; i <= en ; i++)
{
if(path[i]==-1&&gh[tk][i])
{
path[i] = tk;
flow[i] = min(flow[tk],gh[tk][i]);
q.push(i);
}
}
}
if(path[en]==-1)
return -1;
return flow[en];
}
int km()
{
int now,pre,sum=0,k;
while((k=bfs())!=-1)
{
sum+=k;
now = en;
while(now!=st)
{
pre = path[now];
gh[pre][now]-=k;
gh[now][pre]+=k;
now = pre;
}
}
return sum;
}


dinic算法 O(n*n*m)

效率相对于上面快了很多

#define INF 0x3f3f3f
const int N = 415;
#define M 160015
struct node
{
int u,v,next;
int w;
} edge[M<<1];
int head
,t,vis
,pp
,dis
;
int o
;
int st,en;
int x

,f
;
void init()
{
t=0;
memset(head,-1,sizeof(head));
}
void add(int u,int v,int w)
{
edge[t].u = u;
edge[t].v = v;
edge[t].w = w;
edge[t].next = head[u];
head[u] = t++;
edge[t].u = v;
edge[t].v = u;
edge[t].w = 0;
edge[t].next = head[v];
head[v] = t++;
}
int bfs()
{
int i,u;
int w;
memset(dis,-1,sizeof(dis));
queue<int>q;
q.push(st);
dis[st] = 0;
while(!q.empty())
{
u = q.front();
q.pop();
for(i = head[u] ; i != -1 ; i = edge[i].next)
{
int v = edge[i].v;
w = edge[i].w;
if(dis[v]<0&&w>0)
{
dis[v] = dis[u]+1;
q.push(v);
}
}
}
if(dis[en]>0) return 1;
return 0;
}
int dfs(int u,int te)
{
int i;
int s;
if(u==en) return te;
for(i = head[u] ; i != -1 ; i = edge[i].next)
{
int v = edge[i].v;
int w = edge[i].w;
if(w>0&&dis[v]==dis[u]+1&&(s=dfs(v,min(te,w))))
{
edge[i].w-=s;
edge[i^1].w+=s;
return s;
}
}
dis[u] = -1;
return 0;
}
int dinic()
{
int flow = 0;
int res;
while(bfs())
{
while(res = dfs(st,INF))
flow+=res;
}
return flow;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: