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

    题意

    给你n个点,m条边,要求每条边只能走一次的S到T的最短路径的个数


    题解

    在我又WA又TLE还RE时,yyb大佬告诉我说要跑两遍SPFA,还说我写的一遍SPFA是错的,然而

    啪啪打脸。。。
    而且他的

    比我跑得慢,2333
    接下来讲一下方法
    首先一遍SPFA(或dijkstra)从S跑一遍到所有点的最短路,重新建图时对于每对u, v 若 dis[u] + w[u][v] == dis[v] 则加入这条边,容量为1(还要加反边),最后跑最大流即可,最大流我用的是Dinic,然后注意手打队列,系统的会TLE


    常熟巨大的丑陋代码

    # include <bits/stdc++.h>
    # define RG register
    # define IL inline
    # define ll long long
    # define mem(a, b) memset(a, b, sizeof(a))
    # define Min(a, b) (((a) > (b)) ? (b) : (a))
    # define Max(a, b) (((a) < (b)) ? (b) : (a))
    using namespace std;
    
    IL int Get(){
        RG char c = '!'; RG int x = 0, z = 1;
        for(; c > '9' || c < '0'; c = getchar()) z = c == '-' ? -1 : 1;
        for(; c <= '9' && c >= '0'; c = getchar()) x = x * 10 + c - '0';
        return x * z;
    }
    
    const int MAXN = 1001, MAXM = 200001, INF = 2147483647;
    int n, m, ft[MAXN], cnt, ans, dis[MAXN], vis[MAXN], _ft[MAXN], level[MAXN], Q[MAXM];
    struct Edge{
        int to, f, nt;
    } edge[MAXM], _edge[MAXM];
    
    IL void Add(RG int u, RG int v, RG int f){
        edge[cnt] = (Edge){v, f, ft[u]}; ft[u] = cnt++;
    }
    
    IL void Add2(RG int u, RG int v, RG int f){
        _edge[cnt] = (Edge){v, f, _ft[u]}; _ft[u] = cnt++;
    }
    
    IL void SPFA(RG int S, RG int T){
        RG int head = 0, tail = 0;
        Q[0] = S; vis[S] = 1; dis[S] = 0;
        while(head <= tail){
            RG int u = Q[head++]; vis[u] = 0;
            for(RG int e = ft[u]; e != -1; e = edge[e].nt){
                RG int v = edge[e].to, f = edge[e].f + dis[u];
                if(dis[v] > f){
                    dis[v] = f;
                    if(!vis[v]) vis[v] = 1, Q[++tail] = v;
                }
            }
        }
    }
    
    IL bool Bfs(RG int S, RG int T){
        mem(level, 0);
        RG int head = 0, tail = 0;
        Q[0] = S; level[S] = 1;
        while(head <= tail){
            RG int u = Q[head++];
            if(u == T) return 1;
            for(RG int e = _ft[u]; e != -1; e = _edge[e].nt){
                RG int v = _edge[e].to, f = _edge[e].f;
                if(f && !level[v]){
                    level[v] = level[u] + 1;
                    Q[++tail] = v;
                }
            }
        }
        return 0;
    }
    
    IL int Dfs(RG int u, RG int T, RG int maxf){
        if(u == T) return maxf;
        RG int res = 0;
        for(RG int e = _ft[u]; e != -1; e = _edge[e].nt){
            RG int v = _edge[e].to, f = _edge[e].f;
            if(level[u] + 1 == level[v] && f){
                f = Dfs(v, T, Min(f, maxf - res));
                _edge[e].f -= f; _edge[e ^ 1].f += f;
                res += f;
                if(res == maxf) break;
            }
        }
        return res;
    }
    
    int main(){
        RG int T = Get();
        while(T--){
            n = Get(); m = Get();
            mem(ft, -1); mem(dis, 63); mem(_ft, -1); ans = cnt = 0;
            for(RG int i = 1; i <= m; i++){
                RG int u = Get(), v = Get(), f = Get();
                if(u == v) continue;
                Add(u, v, f);
            }
            RG int S = Get(), T = Get(); cnt = 0;
            SPFA(S, T);
            for(RG int i = 1; i <= n; i++)
                for(RG int e = ft[i]; e != -1; e = edge[e].nt)
                    if(dis[i] + edge[e].f == dis[edge[e].to])
                        Add2(i, edge[e].to, 1), Add2(edge[e].to, i, 0);
            while(Bfs(S, T)) ans += Dfs(S, T, INF);
            printf("%d
    ", ans);
        }
        return 0;
    }
  • 相关阅读:
    【2012】笔试面试总结(二)
    sdf数据文件查看小工具
    excel表格中怎样使个别单元格变成只读
    平时收获,供需及取(PPC)
    GDI+ 绘制统计图(2D、3D)
    Com注册
    Pocket PC 录音
    我有自己的"CodeSnippet"了!
    打包Winows Mobile快捷方式中文问题?
    ORA12154: TNS: 无法解析指定的连接标识符问题解决
  • 原文地址:https://www.cnblogs.com/cjoieryl/p/8206406.html
Copyright © 2011-2022 走看看