HDU

 HDU - 3416:http://acm.hdu.edu.cn/showproblem.php?pid=3416

参考:https://www.cnblogs.com/kuangbin/archive/2013/05/04/3059372.html

题意:

   问一个带权值的图中,最多能跑几次最短路,每条路只能走一遍。

思路:

  这道题要利用最大流算法和最短路算法。先要跑两遍dji(),第一遍跑从起点S开始跑一遍正图,第二遍从终点T跑一遍反图。这样后枚举每一条边,看这条边的起点到S的距离+这条边的终点到T的距离+这条边长 == 最短路,如果成立,就把这条边 的容量设为1,加入网络流的图中。最后跑一下最大流就行了。

  自己在枚举点的时候没有搞清楚终点是T,wa了好几发。

#include <algorithm>
#include  <iterator>
#include  <iostream>
#include   <cstring>
#include   <cstdlib>
#include   <iomanip>
#include    <bitset>
#include    <cctype>
#include    <cstdio>
#include    <string>
#include    <vector>
#include     <stack>
#include     <cmath>
#include     <queue>
#include      <list>
#include       <map>
#include       <set>
#include   <cassert>
using namespace std;
//#pragma GCC optimize(3)
//#pragma comment(linker, "/STACK:102400000,102400000")  //c++
#define lson (l , mid , rt << 1)
#define rson (mid + 1 , r , rt << 1 | 1)
#define debug(x) cerr << #x << " = " << x << "
";
#define pb push_back
#define pq priority_queue



typedef long long ll;
typedef unsigned long long ull;

typedef pair<ll ,ll > pll;
typedef pair<int ,int > pii;
typedef pair<int,pii> p3;

//priority_queue<int> q;//这是一个大根堆q
//priority_queue<int,vector<int>,greater<int> >q;//这是一个小根堆q
#define fi first
#define se second
//#define endl '
'

#define OKC ios::sync_with_stdio(false);cin.tie(0)
#define FT(A,B,C) for(int A=B;A <= C;++A)  //用来压行
#define REP(i , j , k)  for(int i = j ; i <  k ; ++i)
//priority_queue<int ,vector<int>, greater<int> >que;

const ll mos = 0x7FFFFFFF;  //2147483647
const ll nmos = 0x80000000;  //-2147483648
const int inf = 0x3f3f3f3f;       
const ll inff = 0x3f3f3f3f3f3f3f3f; //18
const int mod = 1e9+7;
const double esp = 1e-8;
const double PI=acos(-1.0);



template<typename T>
inline T read(T&x){
    x=0;int f=0;char ch=getchar();
    while (ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
    while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    return x=f?-x:x;
}


/*-----------------------showtime----------------------*/
            const int maxn = 2e5+9;
            int n,m,c,ans;
            
            int  dis[2][maxn];
            vector<pii>g[2][maxn];
            //dji
            void dji(int f,int soc){
                for(int i=1; i<=n; i++)dis[f][i] = inf;

                priority_queue<pii>que;
                dis[f][soc] = 0;
                que.push(pii(0,soc));

                while(!que.empty()){
                    pii tmp = que.top();que.pop();
                    int u = tmp.se;
                    if(dis[f][u] < -1*tmp.fi)continue;
                    for(int i=0; i<g[f][u].size(); i++){
                        int v = g[f][u][i].fi;
                        if(dis[f][v] > dis[f][u] + g[f][u][i].se)
                        {
                            dis[f][v] = dis[f][u] + g[f][u][i].se;
                            que.push(pii(-1*dis[f][v], v));
                        }
                    }
                }
            }
            const int maxm = 1e6+9;
            struct Edge
            {
                int u,v,cap;
                Edge(){}
                Edge(int u,int v,int cap):u(u),v(v),cap(cap){}   
            }es[maxm];
            int R,S,T;
            vector<int>tab[maxn];
            int diss[maxn],current[maxn];
            void addedge(int u,int v,int cap){
                tab[u].pb(R);
                es[R++] = Edge(u,v,cap);
                tab[v].pb(R);
                es[R++] = Edge(v,u,0);
            }
            bool BFS(){
                queue<int>q;q.push(S);
                memset(diss,inf,sizeof(diss));
                diss[S] = 0;
                while(!q.empty()){
                    int h = q.front();q.pop();
                    for(int i=0; i<tab[h].size(); i++){
                        Edge & e = es[tab[h][i]];
                        if(e.cap>0 &&diss[e.v] == inf){
                            diss[e.v] = diss[h] + 1;
                            q.push(e.v);
                        }
                    }
                }
                return diss[T] < inf;
            }

            int DFS(int x,int maxflow){
                if(x == T){
                    return maxflow;
                }
                for(int i=current[x]; i<tab[x].size(); i++){
                    current[x] = i;
                    Edge &e = es[tab[x][i]];
                    if(diss[e.v] == diss[x] + 1 && e.cap > 0){
                        int flow = DFS(e.v, min(maxflow, e.cap));
                        if(flow>0){
                            e.cap -= flow;
                            es[tab[x][i] ^ 1].cap += flow;
                            return flow;
                        }
                    }
                }
                return 0;
            }
            int dinic(){
                int ans = 0;
                while(BFS()){
                    int flow;
                    memset(current,0,sizeof(current));
                    while(true){
                        flow = DFS(S,inf);
                        if(flow > 0) ans += flow;
                        else break;
                    }
                }
                return ans;
            }

int main(){
            int t;scanf("%d" , &t);

            while(t--){
                
                scanf("%d%d", &n, &m);    
                for(int i=1; i<=n; i++)g[0][i].clear(),g[1][i].clear(),tab[i].clear();
                for(int i=1; i<=m; i++){
                        int u,v,c;
                        scanf("%d%d%d", &u, &v, &c);
                        if(v == u)continue;
                        g[0][u].pb(pii(v,c));
                        g[1][v].pb(pii(u,c));
                }
                scanf("%d%d", &S, &T);
                
                dji(0,S),dji(1,T);
                // debug(dis[0][n]);
                R = 0;
                for(int i=1; i<=n; i++){
                    for(int j=0; j<g[0][i].size(); j++){
                        int u = i,v = g[0][i][j].fi;
                        if(u!=v && dis[0][T] == dis[0][u] + dis[1][v] + g[0][i][j].se){
                            addedge(u,v,1);
                        }
                    }
                }
                printf("%d
", dinic());
            }
            return 0;
}
HDU - 3416
原文地址:https://www.cnblogs.com/ckxkexing/p/9592901.html