图论模板集合

二分图模板

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

int n1,n2,k;

//n1,n2为二分图的顶点集,其中x∈n1,y∈n2
int map[N][N],vis[N],link[N];
//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[N],flow[N],gh[N][N],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[N],t,vis[N],pp[N],dis[N];
int o[N];
int st,en;
int x[N][N],f[N];
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;
}

 

 

 

posted @ 2014-04-26 19:58  _雨  阅读(235)  评论(0编辑  收藏  举报