HDU3416 Marriage Match IV(最短路+网络流)

给出一个有向图和起点、终点,每条路径只能走一次,询问从起点到终点能重复的走几次。

做法就是从起点到终点来回跑两遍最短路,建一个最短路网络流图。

无需考虑重边和自环,这些不影响Dinic算法的执行。

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+100;
const int inf=1e9+100;
int n,m;
struct node {
    int u,v,w,nxt;
}edge[maxn<<1];
int head[maxn],tot;
void addedge (int u,int v,int w) {
    edge[tot].u=u;
    edge[tot].v=v;
    edge[tot].w=w;
    edge[tot].nxt=head[u];
    head[u]=tot++;
} 
int dep[maxn],inq[maxn],cur[maxn],wjm,maxflow,s,t;
bool bfs () {
    for (int i=0;i<=t;i++) {
        cur[i]=head[i];
        dep[i]=inf;
        inq[i]=0;
    }
    dep[s]=0;
    queue<int> q;
    q.push(s);
    while (q.size()) {
        int u=q.front();
        q.pop();
        inq[u]=0;
        for (int i=head[u];i!=-1;i=edge[i].nxt) {
            int v=edge[i].v;
            if (dep[v]>dep[u]+1&&edge[i].w) {
                dep[v]=dep[u]+1;
                if (inq[v]==0) {
                    q.push(v);
                    inq[v]=1;
                }
            }
        }
    }
    if (dep[t]!=inf) return 1;
    return 0;
}
int dfs (int u,int flow) {
    int increase=0;
    if (u==t) {
        wjm=1;
        maxflow+=flow;
        return flow;
    }
    int used=0;
    for (int i=cur[u];i!=-1;i=edge[i].nxt) {
        cur[u]=i;
        int v=edge[i].v;
        if (edge[i].w&&dep[v]==dep[u]+1) {
            if (increase=dfs(v,min(flow-used,edge[i].w))) {
                used+=increase;
                edge[i].w-=increase;
                edge[i^1].w+=increase;
                if (used==flow) break;
            }
        }
    }
    return used;
}
int Dinic () {
    while (bfs()) {
        wjm=1;
        while (wjm==1) {
            wjm=0;
            dfs(s,inf);
        }
    }
    return maxflow;
}

long long d[maxn][2];
int vis[maxn];
struct qnode {
    int v;
    int w;
    qnode (int vv,int ww) {
        v=vv;
        w=ww;
    }
    bool operator < (const qnode &r) const {
        return w>r.w;
    } 
};
void dij (int s,int f) {
    for (int i=1;i<=n;i++) d[i][f]=inf,vis[i]=0;
    priority_queue<qnode> q;
    d[s][f]=0;
    q.push(qnode(s,d[s][f]));
    while (q.size()) {
        qnode tt=q.top();
        q.pop();
        int u=tt.v;
        vis[u]=1;
        for (int i=head[u];i!=-1;i=edge[i].nxt) {
            int v=edge[i].v;
            if (vis[v]) continue;
            if (d[u][f]+edge[i].w<d[v][f]) {
                d[v][f]=d[u][f]+edge[i].w;
                q.push(qnode(v,d[v][f]));
            }
        }
    }
}
struct E {
    int u,v,w;
    bool operator < (const E &r) const {
        return w<r.w;
    }
}e[maxn];
int F[maxn]; 
int main () {
    int _;
    scanf("%d",&_);
    while (_--) {
        scanf("%d%d",&n,&m);
        for (int i=1;i<=n;i++) head[i]=-1,tot=0;
        for (int i=1;i<=m;i++) F[i]=0;
        for (int i=1;i<=m;i++) {
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            e[i]={u,v,w};
        }
        sort(e+1,e+m+1);
        for (int i=1;i<=m;i++) {
            if (e[i].u==e[i].v) continue;
            addedge(e[i].u,e[i].v,e[i].w);
        }
        int A,B;
        scanf("%d%d",&A,&B);
        dij(A,0);
        for (int i=0;i<=n+1;i++) head[i]=-1;tot=0;
        for (int i=1;i<=m;i++) {
            if (e[i].u==e[i].v) continue;
            addedge(e[i].v,e[i].u,e[i].w);
        }
        dij(B,1);
        s=0;t=n+1;
        for (int i=0;i<=n+1;i++) head[i]=-1;tot=0;wjm=0;maxflow=0;
        addedge(s,A,inf);addedge(A,s,0);
        for (int i=1;i<=m;i++) {
            int u=e[i].u,v=e[i].v,w=e[i].w;
            if (u==v) continue;
            if (d[u][0]+w+d[v][1]==d[B][0]) {
                addedge(u,v,1);
                addedge(v,u,0);
            }
        }
        addedge(B,t,inf);addedge(t,B,0);
        printf("%d\n",Dinic());
    }
}

 

posted @ 2020-11-27 16:27  zlc0405  阅读(54)  评论(0编辑  收藏  举报