hdu6808 Go Running // dinic 网络流

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

网络流之第一次遇见你 ——>基本厚脸皮照搬

感谢HY大佬及参考文献の指点

尽可能写了一点注释方便理解

参考文献:https://blog.csdn.net/weixin_43828245/article/details/107700724

*转载请附链接 谢谢

  1 #include<iostream>
  2 #include<queue>
  3 #include<algorithm>
  4 #include<vector>
  5 #include<iomanip>
  6 #include<cstdio>
  7 #include<cmath>
  8 #include<cstring>
  9 
 10 #define INF 2e9
 11 const int maxn = 2e6 + 10;
 12 using namespace std;
 13 
 14 typedef struct point
 15 {
 16     int flow;
 17     int to;
 18     int next;
 19     point(int a = 0, int b = 0, int c = 0){flow = a, to = b, next = c;} 
 20 } node;
 21 
 22 int n, cnt;
 23 int s, t;//源/汇点
 24 int a[maxn], b[maxn];
 25 int da[maxn], db[maxn];
 26 int head[maxn];//x元素在N数组中的下标即为head[x] 
 27 node N[maxn];
 28 
 29 int deep[maxn];//各点深度 
 30 int hhead[maxn];//dfs中更新headの复制品 
 31 
 32 void Add_Edge(int i, int j, int val)
 33 {
 34     N[cnt].flow = val;
 35     N[cnt].to = j;
 36     N[cnt].next = head[i];
 37     head[i] = cnt++;//从零开始,自增为后缀 
 38 }
 39 
 40 int BFS(int x)//分层网络 
 41 {
 42     memset(deep, 0, sizeof(deep));//除源点外其余点深度为0 
 43     memcpy(hhead, head ,sizeof(hhead));
 44     deep[x] = 1;//源点深度为1
 45     queue<int> q;
 46     q.push(x);
 47     while(!q.empty()){
 48         int now = q.front();//取出队首元素后弹出 
 49         q.pop();
 50         for(int i = head[now] ; i != -1 ; i = N[i].next){//从now节点开始访问 
 51             int nxt = N[i].to, f = N[i].flow;
 52             if(!deep[nxt] && f > 0){//下一点未访问且流量可调整 
 53                 deep[nxt] = deep[now] + 1;
 54                 q.push(nxt);
 55             }
 56         }
 57     }
 58     return deep[t];//汇点若深度为0,则无路可走 
 59 }
 60 
 61 int dfs(int x, int val)//找增广路
 62 {
 63     if(x == t)    return val;
 64     int sum = 0;
 65 
 66     for(int i = hhead[x] ; i != -1 ; i = N[i].next){
 67         hhead[x] = i;
 68         int nxt = N[i].to, f = N[i].flow;
 69         if(f > 0 && deep[nxt] == deep[x] + 1){
 70             int t = dfs(nxt ,min(val - sum, f));//
 71             sum += t;
 72             N[i].flow -= t;
 73             N[i ^ 1].flow += t;//见107行 
 74             if(sum == val)    break;//管道满了 
 75         }
 76     }
 77     
 78     if(sum == 0){//*如果sum==0,那么这个点之前没有增广路,深度清零
 79         deep[x] = 0;
 80     }
 81     return sum;
 82 }
 83 
 84 int main(){
 85     
 86     int T;cin >> T;
 87     while(T--)
 88     {
 89         cin >> n;
 90         memset(head, -1, sizeof(head));//读head数组,直到-1则无路,返回//因而初始化为-1 
 91         cnt = 0;
 92         
 93         int cnta = 0, cntb = 0;
 94         for(int i = 0 ; i < n ; i++){
 95             int t, x;
 96             cin >> t >> x;        
 97             da[i] = a[i] = x - t;
 98             db[i] = b[i] = x + t;            
 99         }
100         //排序(方便lower_bound)+去重
101         sort(da, da + n);
102         cnta = unique(da, da + n) - da;
103         sort(db, db + n);
104         cntb = unique(db, db + n) - db;
105         
106         s = cnta + cntb + 5; t = s + 1;//源点/汇点 
107         //加边时成对进行,因而正反两边的编号也相邻,为了满足异或运算,编号必须从偶数开始
108         /*
109         0 ^ 1 = 1
110         1 ^ 1 = 0
111         2 ^ 1 = 3
112         3 ^ 1 = 2
113         ...
114         */
115         for(int i = 0 ; i < n ; i++){
116             int pos1 = lower_bound(da, da + cnta, a[i]) - da;
117             int pos2 = lower_bound(db, db + cntb, b[i]) - db + cnta + 2;
118             //确定V集下标 
119             Add_Edge(pos1, pos2, 1);//U集与V集
120             Add_Edge(pos2, pos1, 0);
121         }
122         
123         for(int i = 0 ; i < cnta ; i++){
124             Add_Edge(s, i, 1);//源点与U集 
125             Add_Edge(i, s, 0);
126         }
127         
128         for(int i = 0 ; i < cntb ; i++){
129             Add_Edge(i + cnta + 2, t, 1);//汇点与V集 
130             Add_Edge(t, i + cnta + 2, 0);
131         }
132         
133         int res = 0; 
134         while(BFS(s)){//源点开搞 
135             res += dfs(s, INF);
136         }
137         cout << res << endl;
138     }
139     
140     return 0;
141 }
原文地址:https://www.cnblogs.com/ecustlegendn324/p/13491298.html