zoukankan      html  css  js  c++  java
  • HDU 3416 Marriage Match IV (最短路径&&最大流)

    /*
    题意: 有 n 个城市,知道了起点和终点,有 m 条有向边,问从起点到终点的最短路一共有多少条。这是一个有向图,建边的时候要注意!!

    解题思路:这题的关键就是找到哪些边可以构成最短路,其实之前做最短路的题目接触过很多,反向建一个图,求两边最短路,即从src到任一点的最短路dis1[]和从des到任一点的最短路dis2[],那么假设这条边是(u,v,w),如果dis1[u] + w + dis2[v] = dis1[des],说明这条边是构成最短路的边。找到这些边,就可以把边的容量设为1,跑一边最大流即可。
    ————————————————

    代码:

      1 #include<stdio.h>
      2 #include<algorithm>
      3 #include<string.h>
      4 #include<queue>
      5 using namespace std;
      6 const int maxn = 1005;
      7 const int inf = 0x3f3f3f3f;
      8 int t, u, v, w;
      9 struct node
     10 {
     11     int u, v, w, next;
     12 }edge[800005], e[100005];
     13 int head[maxn], dis[2][maxn], pre[2][maxn],level[maxn];
     14 bool vis[maxn];
     15 int n, m, st, ed, tot;
     16 void init()
     17 {
     18     tot = 0;
     19     memset(head, -1, sizeof(head));
     20     memset(pre, -1, sizeof(pre));
     21     return;
     22 }
     23 void addedge(int u, int v, int w)
     24 {
     25     edge[tot].v = v;
     26     edge[tot].w = w;
     27     edge[tot].next = head[u];
     28     head[u] = tot++;
     29     edge[tot].v = u;
     30     edge[tot].w = w;
     31     edge[tot].next = head[v];
     32     head[v] = tot++;
     33     return;
     34 }
     35 void addedge1(int u,int v,int w)
     36 {
     37     edge[tot].v = v;
     38     edge[tot].w = w;
     39     edge[tot].next = pre[0][u];
     40     pre[0][u] = tot++;
     41     return;
     42 }
     43 void addedge2(int u, int v, int w)
     44 {
     45     edge[tot].v = v;
     46     edge[tot].w = w;
     47     edge[tot].next = pre[1][u];
     48     pre[1][u] = tot++;
     49     return;
     50 }
     51 void spfa(int st, int ed, int idx)
     52 {
     53     queue<int>pq;
     54     memset(dis[idx], inf, sizeof(dis[idx]));
     55     memset(vis, false, sizeof(vis));
     56     dis[idx][st] = 0;
     57     pq.push(st);
     58     vis[st] = true;
     59     while (!pq.empty())
     60     {
     61         int u = pq.front();
     62         pq.pop();
     63         vis[u] = false;
     64         for (int i = pre[idx][u]; i != -1; i = edge[i].next)
     65         {
     66             int v = edge[i].v;
     67             if(dis[idx][v] > dis[idx][u] + edge[i].w)
     68             {
     69                 dis[idx][v] = dis[idx][u] + edge[i].w;
     70                 if (!vis[v])
     71                 {
     72                     pq.push(v);
     73                     vis[v] = true;
     74                 }
     75             }
     76         }
     77     }
     78 }
     79 void build()
     80 {
     81     for (int i = 1; i <= m; i++)
     82     {
     83         u = e[i].u;
     84         v = e[i].v;
     85         w = e[i].w;
     86         if (dis[0][u] + dis[1][v] + w == dis[0][ed])
     87         {
     88             addedge(u, v, 1);
     89         }
     90     }
     91 }
     92 int bfs(int st, int ed)
     93 {
     94     queue<int>q;
     95     memset(level, 0, sizeof(level));
     96     level[st] = 1;
     97     q.push(st);
     98     while (!q.empty())
     99     {
    100         int u = q.front();
    101         q.pop();
    102         if (u == ed)
    103         {
    104             return 1;
    105         }
    106         for (int i = head[u]; i != -1; i = edge[i].next)
    107         {
    108             int v = edge[i].v;
    109             int w = edge[i].w;
    110             if (level[v] == 0 && w != 0)
    111             {
    112                 level[v] = level[u] + 1;
    113                 q.push(v);
    114             }
    115         }
    116     }
    117     return -1;
    118 }
    119 int dfs(int st, int ed, int f)
    120 {
    121     if (st == ed)
    122     {
    123         return f;
    124     }
    125     int ret = 0;
    126     for (int i = head[st]; i != -1; i = edge[i].next)
    127     {
    128         int v = edge[i].v;
    129         int w = edge[i].w;
    130         if (level[v] == level[st] + 1 && w != 0)
    131         {
    132             int MIN = min(f - ret, w);
    133             w = dfs(v, ed, MIN);
    134             if (w > 0)
    135             {
    136                 edge[i].w -= w;
    137                 edge[i ^ 1].w += w;
    138                 ret += w;
    139                 if (ret == f)
    140                 {
    141                     return ret;
    142                 }
    143             }
    144             else
    145             {
    146                 level[v] = -1;
    147             }
    148         }
    149     }
    150     return ret;
    151 }
    152 int dinic(int st,int ed)
    153 {
    154     int ans = 0;
    155     while (bfs(st, ed) != -1)
    156     {
    157         ans += dfs(st, ed, inf);
    158     }
    159     return ans;
    160 }
    161 int main()
    162 {
    163     //freopen("C:/input.txt", "r", stdin);
    164     scanf("%d", &t);
    165     while (t--)
    166     {
    167         init();
    168         scanf("%d%d", &n, &m);
    169         for (int i = 1; i <= m; i++)
    170         {
    171             scanf("%d%d%d", &u, &v, &w);
    172             e[i].u = u, e[i].v = v, e[i].w = w;
    173             addedge1(u, v, w);
    174             addedge2(v, u, w);
    175         }
    176         scanf("%d%d", &st, &ed);
    177         spfa(st, ed, 0);
    178         spfa(ed, st, 1);
    179         build();
    180         int maxflow = dinic(st, ed);
    181         printf("%d
    ", maxflow);
    182     }
    183     return 0;
    184 }
    View Code
  • 相关阅读:
    MFC绘图机制(二)-双缓存
    C89:论数组/指针/引用
    C89:论预处理命令
    图像优化大坑
    MFC 对话框和属性表
    jQuery-plugin-pagePiling
    jquery-ui-chosen
    JavaScript DOM编程艺术小笔记
    微信公众号素材
    iOS沙箱传值
  • 原文地址:https://www.cnblogs.com/kongbursi-2292702937/p/11837755.html
Copyright © 2011-2022 走看看