图论模板集合

二分图模板

匈牙利算法 时间复杂度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;

}

 

 

 

你可能感兴趣的:(集合)