• hdu3416 Marriage Match IV(最短路+网络流)


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3416

    题意:

    给出含n个点、m条有向边的图,每条边只能走一次,给出起点和终点,求起点到终点的最短路径有多少条。

    思路:

    题目要求是最短路径,当然需要求出最短路,用Dijkstra就可以了,然后我们需要构造网络流的图。将能组成最短路的边加入图中,容量设为1,注意能组成最短路的边是满足dis[u] + edge[i].dist == dis[v] 的边,其中u是边的起点,v是边的终点,dis[]保存的是最短路。最后跑最大流即可。

    代码如下:

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cmath>
      4 #include<cstring>
      5 #include<queue>
      6 
      7 using namespace std;
      8 const int INF=0x3f3f3f3f;
      9 const int maxn=1100;
     10 const int maxm=110000;
     11 struct node
     12 {
     13     int d,u;
     14     friend bool operator<(node a,node b)
     15     {
     16         return a.d>b.d;
     17     }
     18     node(int dist,int point):d(dist),u(point){}
     19 };
     20 
     21 struct Edge1
     22 {
     23     int to,next;
     24     int dist;
     25 }edge1[maxm];
     26 int head1[maxn],tot;
     27 int pre[maxn],dis[maxn];
     28 bool vis[maxm];
     29 
     30 void init1()
     31 {
     32     memset(head1,-1,sizeof(head1));
     33     tot=0;
     34 }
     35 
     36 void addedge1(int u,int v,int d)
     37 {
     38     edge1[tot].to=v;
     39     edge1[tot].dist=d;
     40     edge1[tot].next=head1[u];
     41     head1[u]=tot++;
     42 }
     43 
     44 void Dijkstra(int s)
     45 {
     46     priority_queue<node> q;
     47     memset(dis,0x3f,sizeof(dis));
     48     memset(pre,-1,sizeof(pre));
     49     dis[s]=0;
     50     while(!q.empty())
     51         q.pop();
     52     node a(0,s);
     53     q.push(a);       
     54     while(!q.empty())
     55     {
     56         node x=q.top();
     57         q.pop();
     58         if(dis[x.u]<x.d)   
     59             continue;
     60         for(int i=head1[x.u];i!=-1;i=edge1[i].next)
     61         {
     62             int v=edge1[i].to;
     63             if(dis[v]>dis[x.u]+edge1[i].dist)
     64             {
     65                 dis[v]=dis[x.u]+edge1[i].dist;
     66                 pre[v]=x.u;
     67                 q.push(node(dis[v],v));
     68             }
     69         }
     70     }
     71 }
     72 const int MAXN = 2010;
     73 const int MAXM = 1200012;
     74 struct Temp
     75 {
     76     int u,v;
     77 }temp[MAXM];
     78 int cnt;
     79 void dfs(int u)
     80 {
     81     for(int i=head1[u];i!=-1;i=edge1[i].next)
     82     {
     83         int v=edge1[i].to;
     84         if(dis[u]+edge1[i].dist==dis[v]&&(!vis[i]))
     85         {
     86             temp[cnt].u=u;
     87             temp[cnt++].v=v;
     88             vis[i]=true;
     89             dfs(v);
     90         }
     91     }
     92 }
     93 
     94 struct Edge2 
     95 {
     96     int to, next, cap, flow;
     97 }edge[MAXM];
     98 int tol;
     99 int head[MAXN];
    100 void init() 
    101 {
    102     tol = 2;
    103     memset(head, -1, sizeof(head));
    104 }
    105 void addedge(int u, int v, int w, int rw=0) 
    106 {
    107     edge[tol].to = v; edge[tol].cap = w; edge[tol].flow = 0;
    108     edge[tol].next = head[u]; head[u] = tol++;
    109     edge[tol].to = u; edge[tol].cap = rw; edge[tol].flow = 0;
    110     edge[tol].next = head[v]; head[v] = tol++;
    111 }
    112 int Q[MAXN];
    113 int dep[MAXN], cur[MAXN], sta[MAXN];
    114 bool bfs(int s, int t, int n) 
    115 {
    116     int front = 0, tail = 0;
    117     memset(dep, -1, sizeof(dep[0])*(n+1));
    118     dep[s] = 0;
    119     Q[tail++] = s;
    120     while(front < tail)
    121     {
    122         int u = Q[front++];
    123         for(int i = head[u]; i != -1; i = edge[i].next) 
    124         {
    125             int v = edge[i].to;
    126             if(edge[i].cap > edge[i].flow && dep[v] == -1)                         {
    127                 dep[v] = dep[u] + 1;
    128                 if(v == t) return true;
    129                 Q[tail++] = v;
    130             }
    131         }
    132     }
    133     return false;
    134 }
    135 int dinic(int s, int t, int n) {
    136     int maxflow = 0;
    137     while(bfs(s, t, n)) {
    138         for(int i = 0; i < n; i++) cur[i] = head[i];
    139         int u = s, tail = 0;
    140         while(cur[s] != -1)
    141         {
    142             if(u == t) 
    143             {
    144                 int tp = INF;
    145                 for(int i = tail-1; i >= 0; i--)
    146                     tp = min(tp, edge[sta[i]].cap-edge[sta[i]].flow);
    147                 maxflow+=tp;
    148                 for(int i = tail-1; i >= 0; i--) {
    149                     edge[sta[i]].flow+=tp;
    150                     edge[sta[i]^1].flow-=tp;
    151                     if(edge[sta[i]].cap-edge[sta[i]].flow==0)
    152                         tail = i;
    153                 }
    154                 u = edge[sta[tail]^1].to;
    155             }
    156             else 
    157                 if(cur[u] != -1 && edge[cur[u]].cap > edge[cur[u]].flow && dep[u] + 1 == dep[edge[cur[u]].to]) 
    158                 {
    159                     sta[tail++] = cur[u];
    160                     u = edge[cur[u]].to;
    161                 }
    162                 else 
    163                 {
    164                     while(u != s && cur[u] == -1)
    165                         u = edge[sta[--tail]^1].to;
    166                     cur[u] = edge[cur[u]].next;
    167                 }
    168         }
    169     }
    170     return maxflow;
    171 }
    172 int n,m,a,b;
    173 
    174 int main()
    175 {
    176     int t;
    177     scanf("%d",&t);
    178     while(t--)
    179     {
    180         init1();
    181         scanf("%d%d",&n,&m);
    182         for(int i=1;i<=m;++i)
    183         {
    184             int u,v,c;
    185             scanf("%d%d%d",&u,&v,&c);
    186             if(u!=v)
    187                 addedge1(u,v,c);
    188         }
    189         scanf("%d%d",&a,&b);
    190         Dijkstra(a);
    191         memset(vis,false,sizeof(vis));
    192         cnt=0;
    193         dfs(a);
    194         init();
    195         for(int i=0;i<cnt;++i)
    196             addedge(temp[i].u-1,temp[i].v-1,1);
    197         int ans=dinic(a-1,b-1,n);
    198         cout<<ans<<endl;
    199     }
    200     return 0;
    201 }
  • 相关阅读:
    C/C++字符串函数之复制函数
    tesseract api C++使用例子
    error C2275: “XXX”: 将此类型用作表达式非法
    Socket通信原理探讨(C++为例)
    模拟按键,点击,滑动,在光标处输出字符
    安卓使用Root权限实现后台模拟全局按键、触屏事件方法(类似按键精灵)
    【 转】__try,__except,__finally,__leave异常模型机制
    提高VS2010运行速度的技巧
    解决VS2010子目录中的.cpp文件引用上一级目录的stdafx.h找不到定义的问题
    1009MySQL数据库InnoDB存储引擎Log漫游
  • 原文地址:https://www.cnblogs.com/yaoyueduzhen/p/5089953.html
Copyright © 2020-2023  润新知