zoukankan      html  css  js  c++  java
  • HDU 3416 Marriage Match IV

    最短路+最大流

    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<vector>
    #include<queue>
    #include<algorithm>
    using namespace std;
    
    const int maxn=1000+10;
    const int MAXN=100000+10;
    const int INF=0x7FFFFFFF;
    
    struct Edge
    {
        int from,to,cap,flow;
    };
    vector<Edge>edges;
    vector<int>G[maxn];
    struct EE1
    {
        int from,to,w;
    } ee1[MAXN];
    struct EE2
    {
        int from,to,w;
    } ee2[MAXN];
    vector<EE1>SPFAG1[maxn];
    vector<EE2>SPFAG2[maxn];
    bool vis[maxn];
    int d[maxn];
    int cur[maxn];
    int U[MAXN],V[MAXN],C[MAXN];
    int FF1[maxn],Dis1[maxn],FF2[maxn],Dis2[maxn];
    int n,m,s,t,N,M;
    
    //求出层次网络
    bool BFS()
    {
        memset(vis,0,sizeof(vis));
        queue<int>Q;
        Q.push(s);
        d[s]=0;
        vis[s]=1;
        while(!Q.empty())
        {
            int x=Q.front();
            Q.pop();
            for(int i=0; i<G[x].size(); i++)
            {
                Edge& e=edges[G[x][i]];
                if(!vis[e.to]&&e.cap>e.flow)
                {
                    vis[e.to]=1;
                    d[e.to]=d[x]+1;
                    Q.push(e.to);
                }
            }
        }
        return vis[t];
    }
    
    //加边
    void AddEdge(int from,int to,int cap)
    {
        Edge r;
        r.from=from;
        r.to=to;
        r.cap=cap;
        r.flow=0;
        edges.push_back(r);
        Edge d;
        d.from=to;
        d.to=from;
        d.cap=0;
        d.flow=0;
        edges.push_back(d);
        m=edges.size();
        G[from].push_back(m-2);
        G[to].push_back(m-1);
    }
    
    //每个阶段来一次DFS增广
    int DFS(int x,int a)
    {
        if(x==t||a==0) return a;
        int flow=0,f;
        for(int i=cur[x]; i<G[x].size(); i++)
        {
            Edge& e=edges[G[x][i]];
            if(d[x]+1==d[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0)
            {
                e.flow+=f;
                edges[G[x][i]^1].flow-=f;
                flow+=f;
                a-=f;
                if(a==0) break;
            }
        }
        return flow;
    }
    
    //多个阶段,多次建立层次网络。
    int Maxflow(int ss,int tt)
    {
        int flow=0;
        while(BFS())
        {
            memset(cur,0,sizeof(cur));
            flow+=DFS(ss,INF);
        }
        return flow;
    }
    
    void SPFA1()
    {
        for(int i=0; i<=N; i++) Dis1[i]=INF;
        queue<int>Q;
        Q.push(s);
        FF1[s]=1;
        Dis1[s]=0;
        while(!Q.empty())
        {
            int h=Q.front();
            Q.pop();
            FF1[h]=0;
            for(int i=0; i<SPFAG1[h].size(); i++)
            {
                EE1 edge=SPFAG1[h][i];
                if(Dis1[h]+edge.w<Dis1[edge.to])
                {
                    Dis1[edge.to]=Dis1[h]+edge.w;
                    if(FF1[edge.to]==0)
                    {
                        FF1[edge.to]=1;
                        Q.push(edge.to);
                    }
                }
            }
        }
    }
    
    void SPFA2()
    {
        for(int i=0; i<=N; i++) Dis2[i]=INF;
        queue<int>Q;
        Q.push(t);
        FF2[t]=1;
        Dis2[t]=0;
        while(!Q.empty())
        {
            int h=Q.front();
            Q.pop();
            FF2[h]=0;
            for(int i=0; i<SPFAG2[h].size(); i++)
            {
                EE2 edge=SPFAG2[h][i];
                if(Dis2[h]+edge.w<Dis2[edge.to])
                {
                    Dis2[edge.to]=Dis2[h]+edge.w;
                    if(FF2[edge.to]==0)
                    {
                        FF2[edge.to]=1;
                        Q.push(edge.to);
                    }
                }
            }
        }
    }
    
    int main()
    {
        int TT;
        scanf("%d",&TT);
        while(TT--)
        {
            scanf("%d%d",&N,&M);
            edges.clear();
            for(int i=0; i<maxn; i++) G[i].clear();
            for(int i=0; i<maxn; i++) SPFAG1[i].clear();
            for(int i=0; i<maxn; i++) SPFAG2[i].clear();
            for(int i=1; i<=M; i++)
            {
                scanf("%d%d%d",&U[i],&V[i],&C[i]);
                ee1[i].from=U[i];
                ee1[i].to=V[i];
                ee1[i].w=C[i];
                ee2[i].from=V[i];
                ee2[i].to=U[i];
                ee2[i].w=C[i];
                SPFAG1[U[i]].push_back(ee1[i]);
                SPFAG2[V[i]].push_back(ee2[i]);
            }
            scanf("%d%d",&s,&t);
            SPFA1();SPFA2();
            for(int i=1; i<=M; i++)
                if(Dis1[U[i]]+Dis2[V[i]]+C[i]==Dis1[t])
                    AddEdge(U[i],V[i],1);
            printf("%d
    ",Maxflow(s,t));
        }
        return 0;
    }
  • 相关阅读:
    Struts2SpringHibernate整合示例,一个HelloWorld版的在线书店(项目源码+详尽注释+单元测试)
    Java实现蓝桥杯勇者斗恶龙
    Java实现 LeetCode 226 翻转二叉树
    Java实现 LeetCode 226 翻转二叉树
    Java实现 LeetCode 226 翻转二叉树
    Java实现 LeetCode 225 用队列实现栈
    Java实现 LeetCode 225 用队列实现栈
    Java实现 LeetCode 225 用队列实现栈
    Java实现 LeetCode 224 基本计算器
    Java实现 LeetCode 224 基本计算器
  • 原文地址:https://www.cnblogs.com/zufezzt/p/4752647.html
Copyright © 2011-2022 走看看