[AHOI 2006] 上学路线

[题目链接]

        https://www.lydsy.com/JudgeOnline/problem.php?id=1266

[算法]

        首先 , 用Dijkstra求单源最短路

        然后 , 建出这张图G的最短路图G’ , 答案即为G'的最小割

        最大流最小割定理 : 最小割 = 最大流 

        直接求最大流即可

        时间复杂度 : O(Dinic(N , M))

[代码]

      

#include<bits/stdc++.h>
using namespace std;
#define MAXN 500010
const int inf = 2e9;

struct edge
{
        int to , w , nxt;
} e[MAXN << 1];

int n , tot , m;
int u[MAXN] , v[MAXN] , w[MAXN] , c[MAXN] , head[MAXN] , depth[MAXN] , dist[MAXN];
bool visited[MAXN];

template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
template <typename T> inline void read(T &x)
{
    T f = 1; x = 0;
    char c = getchar();
    for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
    for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
    x *= f;
}
inline void addedge(int u , int v , int w)
{
        ++tot;
        e[tot] = (edge){v , w , head[u]};
        head[u] = tot;
}
inline void addedgeF(int u , int v , int w)
{
        ++tot;
        e[tot] = (edge){v , w , head[u]};
        head[u] = tot;
        ++tot;
        e[tot] = (edge){u , 0 , head[v]};
        head[v] = tot;
}
inline void dijkstra()
{
        priority_queue< pair<int , int> , vector< pair<int , int> > , greater< pair<int , int> > > q;
        for (int i = 1; i <= n; i++) 
        {
                dist[i] = inf;
                visited[i] = false;
        }
        dist[1] = 0;
        q.push(make_pair(0 , 1));
        while (!q.empty())
        {
                int cur = q.top().second;
                q.pop();
                if (visited[cur]) continue;
                visited[cur] = true;
                for (int i = head[cur]; i; i = e[i].nxt)
                {
                        int v = e[i].to , w = e[i].w;
                        if (dist[cur] + w < dist[v])
                        {
                                dist[v] = dist[cur] + w;
                                q.push(make_pair(dist[v] , v));
                        }
                }
        }
}
inline bool bfs()
{
        int l , r;
        static int q[MAXN];    
        memset(depth , 0 , sizeof(depth));
        q[depth[l = r = 1] = 1] = 1;
        while (l <= r)
        {
                int cur = q[l++];
                for (int i = head[cur]; i; i = e[i].nxt)
                {
                        int v = e[i].to , w = e[i].w;
                        if (w > 0 && !depth[v])
                        {
                                depth[v] = depth[cur] + 1;
                                q[++r] = v;
                        }
                }
        }
        if (depth[n] > 0) return true;
        else return false;
}
inline int dinic(int u , int flow)
{
        int rest = flow;
        if (u == n) return flow;
        for (int i = head[u]; i && rest; i = e[i].nxt)
        {
                int v = e[i].to , w = e[i].w;
                if (depth[v] == depth[u] + 1 && w > 0)
                {
                        int k = dinic(v , min(rest , w));
                        if (!k) depth[v] = 0;
                        e[i].w -= k;
                        e[i ^ 1].w += k;
                        rest -= k;
                }        
        }        
        return flow - rest;
}

int main()
{
        
        read(n); read(m);
        for (int i = 1; i <= m; i++)
        {
                read(u[i]); read(v[i]); read(w[i]); read(c[i]);
                addedge(u[i] , v[i] , w[i]);    
                addedge(v[i] , u[i] , w[i]);    
        }
        dijkstra();
        printf("%d
" , dist[n]);
        tot = 1;
        for (int i = 1; i <= n; i++) head[i] = 0;
        for (int i = 1; i <= m; i++)
        {
                if (dist[u[i]] + w[i] == dist[v[i]]) addedgeF(u[i] , v[i] , c[i]);
                if (dist[v[i]] + w[i] == dist[u[i]]) addedgeF(v[i] , u[i] , c[i]);        
        }
        int ans = 0;
        while (bfs())
        {
                while (int flow = dinic(1 , inf))    ans += flow;
        }
        printf("%d
" , ans);
        
        return 0;
    
}
原文地址:https://www.cnblogs.com/evenbao/p/9933826.html