# Island Transport

http://acm.hdu.edu.cn/showproblem.php?pid=4280

Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 13032    Accepted Submission(s): 4097

Problem Description
In the vast waters far far away, there are many islands. People are living on the islands, and all the transport among the islands relies on the ships.
You have a transportation company there. Some routes are opened for passengers. Each route is a straight line connecting two different islands, and it is bidirectional. Within an hour, a route can transport a certain number of passengers in one direction. For safety, no two routes are cross or overlap and no routes will pass an island except the departing island and the arriving island. Each island can be treated as a point on the XY plane coordinate system. X coordinate increase from west to east, and Y coordinate increase from south to north.
The transport capacity is important to you. Suppose many passengers depart from the westernmost island and would like to arrive at the easternmost island, the maximum number of passengers arrive at the latter within every hour is the transport capacity. Please calculate it.

Input
The first line contains one integer T (1<=T<=20), the number of test cases.
Then T test cases follow. The first line of each test case contains two integers N and M (2<=N,M<=100000), the number of islands and the number of routes. Islands are number from 1 to N.
Then N lines follow. Each line contain two integers, the X and Y coordinate of an island. The K-th line in the N lines describes the island K. The absolute values of all the coordinates are no more than 100000.
Then M lines follow. Each line contains three integers I1, I2 (1<=I1,I2<=N) and C (1<=C<=10000) . It means there is a route connecting island I1 and island I2, and it can transport C passengers in one direction within an hour.
It is guaranteed that the routes obey the rules described above. There is only one island is westernmost and only one island is easternmost. No two islands would have the same coordinates. Each island can go to any other island by the routes.

Output
For each test case, output an integer in one line, the transport capacity.

Sample Input

2
5 7
3 3
3 0
3 1
0 0
4 5
1 3 3
2 3 4
2 4 3
1 5 6
4 5 3
1 4 4
3 4 2
6 7
-1 -1
0 1
0 2
1 0
1 1
2 3
1 2 1
2 3 6
4 5 5
5 6 3
1 4 6
2 5 5
3 6 4

Sample Output
9 6  ```  1 #include<iostream>
2 #include<cstring>
3 #include<string>
4 #include<cmath>
5 #include<cstdio>
6 #include<algorithm>
7 #include<queue>
8 #include<vector>
9 #include<set>
10 #define maxn 100005
11 #define MAXN 100005
12 #define mem(a,b) memset(a,b,sizeof(a))
13 const int N=200005;
14 const int M=200005;
15 const int INF=0x3f3f3f3f;
16 using namespace std;
17 int n;
18 struct Edge{
19     int v,next;
20     int cap,flow;
21 }edge[MAXN*20];//注意这里要开的够大。。不然WA在这里真的想骂人。。问题是还不报RE。。
22 int cur[MAXN],pre[MAXN],gap[MAXN],path[MAXN],dep[MAXN];
23 int cnt=0;//实际存储总边数
24 void isap_init()
25 {
26     cnt=0;
27     memset(pre,-1,sizeof(pre));
28 }
29 void isap_add(int u,int v,int w)//加边
30 {
31     edge[cnt].v=v;
32     edge[cnt].cap=w;
33     edge[cnt].flow=0;
34     edge[cnt].next=pre[u];
35     pre[u]=cnt++;
36 }
37 void add(int u,int v,int w){
40 }
41 bool bfs(int s,int t)//其实这个bfs可以融合到下面的迭代里，但是好像是时间要长
42 {
43     memset(dep,-1,sizeof(dep));
44     memset(gap,0,sizeof(gap));
45     gap=1;
46     dep[t]=0;
47     queue<int>q;
48     while(!q.empty())
49     q.pop();
50     q.push(t);//从汇点开始反向建层次图
51     while(!q.empty())
52     {
53         int u=q.front();
54         q.pop();
55         for(int i=pre[u];i!=-1;i=edge[i].next)
56         {
57             int v=edge[i].v;
58             if(dep[v]==-1&&edge[i^1].cap>edge[i^1].flow)//注意是从汇点反向bfs，但应该判断正向弧的余量
59             {
60                 dep[v]=dep[u]+1;
61                 gap[dep[v]]++;
62                 q.push(v);
63                 //if(v==sp)//感觉这两句优化加了一般没错，但是有的题可能会错，所以还是注释出来，到时候视情况而定
64                 //break;
65             }
66         }
67     }
68     return dep[s]!=-1;
69 }
70 int isap(int s,int t)
71 {
72     if(!bfs(s,t))
73     return 0;
74     memcpy(cur,pre,sizeof(pre));
75     //for(int i=1;i<=n;i++)
76     //cout<<"cur "<<cur[i]<<endl;
77     int u=s;
78     path[u]=-1;
79     int ans=0;
80     while(dep[s]<n)//迭代寻找增广路,n为节点数
81     {
82         if(u==t)
83         {
84             int f=INF;
85             for(int i=path[u];i!=-1;i=path[edge[i^1].v])//修改找到的增广路
86                 f=min(f,edge[i].cap-edge[i].flow);
87             for(int i=path[u];i!=-1;i=path[edge[i^1].v])
88             {
89                 edge[i].flow+=f;
90                 edge[i^1].flow-=f;
91             }
92             ans+=f;
93             u=s;
94             continue;
95         }
96         bool flag=false;
97         int v;
98         for(int i=cur[u];i!=-1;i=edge[i].next)
99         {
100             v=edge[i].v;
101             if(dep[v]+1==dep[u]&&edge[i].cap-edge[i].flow)
102             {
103                 cur[u]=path[v]=i;//当前弧优化
104                 flag=true;
105                 break;
106             }
107         }
108         if(flag)
109         {
110             u=v;
111             continue;
112         }
113         int x=n;
114         if(!(--gap[dep[u]]))return ans;//gap优化
115         for(int i=pre[u];i!=-1;i=edge[i].next)
116         {
117             if(edge[i].cap-edge[i].flow&&dep[edge[i].v]<x)
118             {
119                 x=dep[edge[i].v];
120                 cur[u]=i;//常数优化
121             }
122         }
123         dep[u]=x+1;
124         gap[dep[u]]++;
125         if(u!=s)//当前点没有增广路则后退一个点
126         u=edge[path[u]^1].v;
127      }
128      return ans;
129 }
130
131 struct Point{
132     int x,y;
133 }p[maxn];
134
135 int main(){
136     std::ios::sync_with_stdio(false);
137     int m,s,t;
138     int T;
139     cin>>T;
140     while(T--){
141         cin>>n>>m;
142         for(int i=1;i<=n;i++) cin>>p[i].x>>p[i].y;
143         int a,b,c;
144         isap_init();
145         for(int i=1;i<=m;i++){
146             cin>>a>>b>>c;
148         }
149         Point tmp=p;
150         s=1;
151         for(int i=1;i<=n;i++){
152             if(tmp.x>p[i].x){
153                 tmp=p[i];
154                 s=i;
155             }
156         }
157         tmp=p;
158         t=1;
159         for(int i=1;i<=n;i++){
160             if(tmp.x<p[i].x){
161                 tmp=p[i];
162                 t=i;
163             }
164         }
165         cout<<isap(s,t)<<endl;
166     }
167 }```
View Code
• 相关阅读:
如何把git上的小程序项目跑起来
异常好用的六种vue组件通信方式
2021.8.10面试总结
高频面试题总结
21年8.6面试总结
2021.8.4上海微创软件(主react)电话面试
promis封装各种请求
各个框架解决跨域问题
华人运通(主vue)前端研发初级工程师
css常用命名
• 原文地址：https://www.cnblogs.com/Fighting-sh/p/9946251.html