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

    Marriage Match IV

    思路:属于最短路径上的边应该满足:dis_A[u] + dis_B[v] + w == dis_A[B],dis_A是出发点到其他点的距离,dis_B是终点到其他点的距离,u,v是边的两个端点,w是权值。题目说每条边只能用一次,我们可以用最大流算法来求最短路径有几条。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <algorithm>
      4 #include <queue>
      5 #include <vector>
      6 
      7 using namespace std;
      8 
      9 #define ll long long
     10 #define pb push_back
     11 #define fi first
     12 #define se second
     13 
     14 const int N = 1010;
     15 const int M = 1e5;
     16 const int INF = 1e9;
     17 struct node{
     18     int x, d;
     19     bool friend operator<(const node& a, const node& b){
     20         return a.d > b.d;
     21     }
     22 };
     23 struct edge{
     24     int to, nxt, flow;
     25 }e[M << 1];
     26 vector<pair<int, int> > E[2][N];
     27 int dis[2][N];
     28 priority_queue<node > que; //最短路
     29 queue<int > Q;//网络流分层
     30 int d[N];//层级
     31 int n, m, A, B;
     32 int head[N], cur[N], vis[N], id[N]; //链式,当前弧优化,...,编号记录
     33 int tot, cnt;
     34 
     35 void dijkstra(int now, int pos)
     36 {
     37     for(int i = 0; i <= n; ++i) dis[pos][i] = INF;
     38     while(!que.empty()) que.pop();
     39     dis[pos][now] = 0;
     40     que.push({now, 0});
     41 
     42     while(!que.empty()){
     43         int u = que.top().x;
     44         que.pop();
     45 
     46         for(auto e : E[pos][u]){
     47             int v = e.fi;
     48             int w = e.se;
     49 
     50             if(dis[pos][v] > dis[pos][u] + w){
     51                 dis[pos][v] = dis[pos][u] + w;
     52                 que.push({v, dis[pos][v]});
     53             }
     54         }
     55     }
     56     
     57 }
     58 
     59 inline void add(int u, int v)
     60 {
     61     e[tot].to = v; e[tot].flow = 1;
     62     e[tot].nxt = head[u]; head[u] = tot++;
     63     e[tot].to = u; e[tot].flow = 0;
     64     e[tot].nxt = head[v]; head[v] = tot++;
     65 }
     66 
     67 void build()
     68 {
     69     for(int i = 0; i <= n; ++i) head[i] = -1; tot = 0;
     70     for(int x = 1; x <= n; ++x){
     71         for(auto e : E[0][x]){
     72             int y = e.fi;
     73             int w = e.se;
     74             if(dis[0][x] + dis[1][y] + w == dis[0][B] || dis[0][y] + dis[1][x] + w == dis[0][B]){
     75                 if(!vis[x]) id[cnt++] = x, vis[x] = 1;
     76                 if(!vis[y]) id[cnt++] = y, vis[y] = 1;
     77                 add(x, y);
     78             }
     79         }   
     80     }
     81 }
     82 
     83 bool bfs()
     84 {
     85     while(!Q.empty()) que.pop();
     86     for(int i = 0; i < cnt; ++i) {
     87         d[id[i]] = 0;
     88     }
     89     d[A] = 1;
     90     Q.push(A);
     91 
     92     while(!Q.empty()){
     93         int now = Q.front();
     94 
     95         Q.pop();
     96 
     97         for(int o = head[now]; ~o; o = e[o].nxt){
     98             int to = e[o].to;
     99             int flow = e[o].flow;
    100 
    101             if(flow && !d[to]){
    102                 d[to] = d[now] + 1;
    103                 Q.push(to);
    104             }
    105         }
    106     }
    107 
    108     if(!d[B]) return false;
    109     else return true;
    110 }
    111 
    112 int dfs(int now, int pre_flow){
    113     if(now == B) return pre_flow;
    114     int sum = 0;
    115     for(int& o = cur[now]; ~o; o = e[o].nxt){
    116         int to = e[o].to;
    117         int flow = e[o].flow;
    118 
    119         if(flow && d[to] == d[now] + 1){
    120             int tmp = dfs(to, min(pre_flow - sum, flow));
    121             if(tmp == 0) continue;
    122             e[o].flow -= tmp;
    123             e[o ^ 1].flow += tmp;
    124             sum += tmp;
    125             if(sum == pre_flow) return sum;
    126         }
    127     }
    128     return sum;
    129 }
    130 
    131 void dinic()
    132 {
    133     int mf = 0;
    134     while(bfs()){
    135         for(int i = 0; i < cnt; ++i) cur[id[i]] = head[id[i]];
    136         mf += dfs(A, INF);
    137     }
    138 
    139     printf("%d
    ", mf);
    140 }
    141 
    142 void init(){
    143     for(int i = 0; i <= n; ++i){
    144         E[0][i].clear();
    145         E[1][i].clear();
    146     }
    147     for(int i = 0; i < cnt; ++i) vis[id[i]] = 0;
    148     cnt = 0;
    149 }
    150 
    151 void solve()
    152 {
    153     int T;
    154     scanf("%d", &T);
    155 
    156     while(T--){
    157         scanf("%d%d", &n, &m);
    158         
    159         init();
    160 
    161         int u, v, w;
    162         for(int i = 0; i < m; ++i){
    163             scanf("%d%d%d", &u, &v, &w);
    164             if(u == v) continue;
    165             E[0][u].pb(make_pair(v, w));
    166             E[1][v].pb(make_pair(u, w));
    167         }
    168         scanf("%d%d", &A, &B);
    169         dijkstra(A, 0);
    170         dijkstra(B, 1);
    171 
    172         build();
    173         dinic(); 
    174     }
    175 }
    176 
    177 int main()
    178 {
    179 
    180     solve();
    181 
    182     return 0;
    183 }
  • 相关阅读:
    jquery遍历table的tr获取td的值
    Java判断文件、文件夹是否存在
    项目搭建系列之三:SpringMVC框架下使用Ehcache对象、数据缓存
    J2EE课程设计:在线书店管理系统
    项目搭建系列之二:SpringMVC框架下配置MyBatis
    使用Git(msysgit)和TortoiseGit上传代码到GitHub
    安卓课程设计:微课表
    项目搭建系列之一:使用Maven搭建SpringMVC项目
    常用markdown语法
    [转]优秀程序员应该做的几件事
  • 原文地址:https://www.cnblogs.com/SSummerZzz/p/13220282.html
Copyright © 2011-2022 走看看