【HDUOJ】4280 Island Transport
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4280
题意:有n个岛屿,m条无向路,每个路给出最大允许的客流量,求从最西的那个岛屿最多能运用多少乘客到最东的那个岛屿
题解:最大流的裸题。输入记得找到最西和最东的岛屿,以及注意是双向边。。这题用的sap.
代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<cstdlib> 6 #include<string> 7 #include<queue> 8 #include<algorithm> 9 using namespace std; 10 11 const int N=100010; 12 const int M=400010; 13 const int inf=0xfffffff; 14 15 int n,m,cnt; 16 17 struct Edge{ 18 int v , cap , next; 19 } edge[M]; 20 21 int head[N],pre[N],d[N],numd[N]; 22 int cur_edge[N]; 23 24 void addedge(int u,int v,int c){ 25 edge[cnt].v = v; 26 edge[cnt].cap = c; 27 edge[cnt].next = head[u]; 28 head[u] = cnt++; 29 30 edge[cnt].v = u; 31 edge[cnt].cap = 0; 32 edge[cnt].next = head[v]; 33 head[v] = cnt++; 34 } 35 36 void bfs(int s){ 37 memset(numd,0,sizeof(numd)); 38 for(int i=1; i<=n; i++) numd[ d[i] = n ]++; 39 d[s] = 0; 40 numd[n]--; 41 numd[0]++; 42 queue<int> Q; 43 Q.push(s); 44 45 while(!Q.empty()){ 46 int v=Q.front(); 47 Q.pop(); 48 49 int i=head[v]; 50 while(i != -1){ 51 int u=edge[i].v; 52 53 if(d[u]<n){ 54 i=edge[i].next; 55 continue ; 56 } 57 58 d[u] = d[v]+1; 59 numd[n]--; 60 numd[d[u]]++; 61 Q.push(u); 62 i=edge[i].next; 63 } 64 } 65 } 66 67 int SAP(int s,int t){ 68 for(int i = 1; i <= n; i++) cur_edge[i] = head[i]; 69 int max_flow = 0; 70 bfs(t); 71 int u = s ; 72 while(d[s] < n){ 73 if(u == t){ 74 int cur_flow = inf,neck; 75 for(int from = s; from != t; from = edge[cur_edge[from]].v){ 76 if(cur_flow > edge[cur_edge[from]].cap){ 77 neck = from; 78 cur_flow = edge[cur_edge[from]].cap; 79 } 80 } 81 82 for(int from = s; from != t; from = edge[cur_edge[from]].v){ //修改增广路上的边的容量 83 int tmp = cur_edge[from]; 84 edge[tmp].cap -= cur_flow; 85 edge[tmp^1].cap += cur_flow; 86 } 87 max_flow += cur_flow; 88 u = neck; 89 } 90 91 int i; 92 for(i = cur_edge[u]; i != -1; i = edge[i].next) 93 if(edge[i].cap && d[u] == d[edge[i].v]+1) 94 break; 95 96 if(i != -1){ 97 cur_edge[u] = i; 98 pre[edge[i].v] = u; 99 u = edge[i].v; 100 } 101 else{ 102 numd[d[u]]--; 103 if(!numd[d[u]]) break; 104 cur_edge[u] = head[u]; 105 int tmp = n; 106 for(int j = head[u]; j != -1; j = edge[j].next) 107 if(edge[j].cap && tmp > d[edge[j].v]) 108 tmp = d[edge[j].v]; 109 110 d[u] = tmp+1; 111 numd[d[u]]++; 112 if(u != s) 113 u = pre[u]; 114 } 115 } 116 return max_flow; 117 } 118 119 inline void pre_init(){ 120 cnt = 0; 121 memset(head, -1, sizeof head); 122 } 123 124 void mapping(){ 125 int u, v, w; 126 for(int i = 1; i <= m; ++i){ 127 scanf("%d %d %d", &u, &v, &w); 128 addedge(u, v, w); 129 addedge(v, u, w); 130 } 131 } 132 133 int main(){ 134 135 int tcase; 136 scanf("%d",&tcase); 137 while(tcase--){ 138 scanf("%d%d",&n,&m); 139 int x,y,s,t; 140 int minn = inf, maxx = -inf; 141 for(int i = 1; i <= n; i++){ 142 scanf("%d%d",&x,&y); 143 if(x <= minn){ 144 s = i; 145 minn = x; 146 } 147 if(x >= maxx){ 148 t = i; 149 maxx = x; 150 } 151 } 152 pre_init(); 153 mapping(); 154 int ans = SAP(s,t); 155 printf("%d\n",ans); 156 } 157 return 0; 158 }