• hdu-3416(最短路+网络流)


    题意:给你一个有向权图,问你从S到E有几条最短路,每条边直走一次的情况下;

    解题思路:每条边直走一次,最大流边权为1,因为要算几条最短路,那么能得到最短路的路径标记下,然后跑最大流

    代码:

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cstdio>
    #include<queue>
    using namespace std;
    const int inf=0x3f3f3f3f;
    const int maxm=100500;
    const int maxn=1050;
    struct Edge
    {
        int next;int to;int w;int fa;
    }edge[maxm],edge2[maxm];
    struct node
    {
        int num;
        int dist;
        node(int _num=0,int _dist=0):num(_num),dist(_dist){}
        friend bool operator<(node a,node b)
        {
            return a.dist>b.dist;
        }
    };
    int head[maxn],head2[maxn],cnt,cnt2;
    int dist[maxn],n,m,Start,End;
    int depth[maxn];
    int x[maxm],y[maxm],w[maxm];
    void add(int u,int v,int w)
    {
        edge[cnt].next=head[u];edge[cnt].to=v;edge[cnt].w=w;head[u]=cnt++;
    }
    void add2(int u,int v,int w)
    {
        edge2[cnt2].next=head2[u];edge2[cnt2].to=v;edge2[cnt2].w=w;edge2[cnt2].fa=u;head2[u]=cnt2++;
        edge2[cnt2].next=head2[v];edge2[cnt2].to=u;edge2[cnt2].w=0;edge2[cnt2].fa=v;head2[v]=cnt2++;
    }
    void dij(int x)
    {
        memset(dist,inf,sizeof(dist));
        priority_queue<node>q;q.push(node(x,0));dist[x]=0;
        while(!q.empty())
        {
            node u=q.top();q.pop();int now=u.num;
            for(int i=head[now];i!=-1;i=edge[i].next)
            {
                int v=edge[i].to;
                if(dist[v]>dist[now]+edge[i].w)
                {
                    dist[v]=dist[now]+edge[i].w;q.push(node(v,dist[v]));
                }
            }
        }
    }
    bool bfs()//分层;
    {
        memset(depth,0,sizeof(depth));
        queue<int>q;
        q.push(Start);
        depth[Start]=1;
        while(!q.empty())
        {
            int temp=q.front();
            q.pop();
            for(int i=head2[temp];i!=-1;i=edge2[i].next)
            {
                int v=edge2[i].to;
                if(depth[v]||edge2[i].w<=0)
                    continue;
                depth[v]=depth[temp]+1;
                q.push(v);
            }
        }
        return depth[End];//若为0表示没法到达也就是没有路径了;
    }
    int dfs(int u,int maxflow)
    {
        if(u==End)
            return maxflow;
        int add=0;
        for(int i=head2[u];i!=-1&&add<maxflow;i=edge2[i].next)
        {
            int v=edge2[i].to;
            if(depth[v]!=depth[u]+1)
                continue;
            if(edge2[i].w==0)
                continue;
            int tempflow=dfs(v,min(edge2[i].w,maxflow-add));
            edge2[i].w-=tempflow;
            edge2[i^1].w+=tempflow;
            add+=tempflow;
        }
        return add;
    }
    int dinic()
    {
        int ans=0;
        while(bfs())
        {
            ans+=dfs(Start,inf);
        }
        return ans;
    }
    int main()
    {
        int tt;
        scanf("%d",&tt);
        while(tt--)
        {
            scanf("%d%d",&n,&m);
            memset(head,-1,sizeof(head));memset(head2,-1,sizeof(head2));cnt=cnt2=0;
            for(int i=1;i<=m;i++)
            {
                scanf("%d%d%d",&x[i],&y[i],&w[i]);add(x[i],y[i],w[i]);
            }
            scanf("%d%d",&Start,&End);
            dij(Start);
            for(int i=1;i<=m;i++)
                if(dist[y[i]]==dist[x[i]]+w[i])
                    add2(x[i],y[i],1);
            int ans=dinic();
            printf("%d
    ",ans);
        }
    }
    

      

  • 相关阅读:
    TreeMap
    索引
    B-树、B+树
    硬盘速度、存储方式
    2-3树
    多叉树、2-3-4树
    红黑树
    平衡树、AVL树
    树、多路树、二叉树
    Java实现后缀表达式建立表达式树
  • 原文地址:https://www.cnblogs.com/huangdao/p/10309084.html
Copyright © 2020-2023  润新知