最大流最小割
分类:
IT文章
•
2022-07-29 00:34:16
ZOJ Problem Set - 3792 Romantic Value http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5300
模板题,有两种统计边数的办法,一种是扩大边权flow*=mod,然后加flow+=1,最后的最小割就是flow/mod,最小割边数是flow%mod。
dinic
1 #include<cstdio>
2 #include<cstring>
3 #include<iostream>
4 #include<algorithm>
5 #include<queue>
6 #define mt(a,b) memset(a,b,sizeof(a))
7 using namespace std;
8 const int inf=0x3f3f3f3f;
9 class Dinic { ///最大流(MV^2*ME)
10 typedef int typef;///流量的类型
11 static const int ME=4010;///边的个数
12 static const int MV=64;///点的个数
13 int temp[MV],cur[MV],level[MV],path[MV];
14 bool used[MV];
15 queue<int> q;
16 typef flow;
17 bool bfs(int s,int t) {
18 mt(level,-1);
19 while(!q.empty()) q.pop();
20 q.push(s);
21 level[s]=1;
22 while(!q.empty()) {
23 int u=q.front();
24 q.pop();
25 for(int i=g.head[u]; ~i; i=g.e[i].next) {
26 int v=g.e[i].v;
27 if(level[v]==-1&&g.e[i].flow) {
28 level[v]=level[u]+1;
29 q.push(v);
30 if(v==t) return true;
31 }
32 }
33 }
34 return false;
35 }
36 struct G {
37 struct E {
38 int u,v,next;
39 typef flow;
40 } e[ME];
41 int le,head[MV];
42 void init() {
43 le=0;
44 mt(head,-1);
45 }
46 void add(int u,int v,typef flow) {
47 e[le].u=u;
48 e[le].v=v;
49 e[le].flow=flow;
50 e[le].next=head[u];
51 head[u]=le++;
52 }
53 } g;
54 public:
55 typef getflow() {
56 return flow;
57 }
58 void init() {
59 g.init();
60 }
61 void add(int u,int v,typef flow) {
62 g.add(u,v,flow);
63 g.add(v,u,0);
64 }
65 void solve(int s,int t) {
66 int p,tempp;
67 typef now;
68 bool flag;
69 flow=0;
70 while(bfs(s,t)) {
71 for(int i=0; i<MV; i++) {
72 temp[i]=g.head[i];
73 used[i]=true;
74 }
75 p=1;
76 path[p]=s;
77 while(p) {
78 int u=path[p];
79 if(u==t) {
80 now=inf;
81 for(int i=1; i<p; i++) {
82 now=min(now,g.e[cur[path[i]]].flow);
83 }
84 flow+=now;
85 for(int i=1; i<p; i++) {
86 int j=cur[path[i]];
87 g.e[j].flow-=now;
88 g.e[j^1].flow+=now;
89 if(!g.e[j].flow) tempp=i;
90 }
91 p=tempp;
92 } else {
93 flag=false;
94 for(int i=temp[u]; ~i; i=g.e[i].next) {
95 int v=g.e[i].v;
96 if(used[v]&&g.e[i].flow&&level[u]+1==level[v]) {
97 cur[u]=i;
98 temp[u]=g.e[i].next;
99 flag=true;
100 path[++p]=v;
101 break;
102 }
103 }
104 if(flag) continue;
105 p--;
106 used[u]=false;
107 }
108 }
109 }
110 }
111 } dinic;
112 int main() {
113 int t,n,m,p,q,x,y,z;
114 while(~scanf("%d",&t)) {
115 while(t--) {
116 scanf("%d%d%d%d",&n,&m,&p,&q);
117 dinic.init();
118 int sum=0;
119 for(int i=0; i<m; i++) {
120 scanf("%d%d%d",&x,&y,&z);
121 dinic.add(x,y,z*2000+1);
122 dinic.add(y,x,z*2000+1);
123 sum+=z;
124 }
125 dinic.solve(p,q);
126 int ans=dinic.getflow();
127 int ans1 = ans/2000;//我是把边的权值乘以2000, 然后+1
128 int ans2 = ans%2000;//这样%2000就是最小割的边数, /2000就是最小割了。
129 if(ans == 0)printf("Inf
");
130 else printf("%.2f
",(sum-ans1)*1.0/ans2);
131 }
132 }
133 return 0;
134 }
View Code
sap
1 #include<cstdio>
2 #include<cstring>
3 #include<queue>
4 #define mt(a,b) memset(a,b,sizeof(a))
5 using namespace std;
6 const int inf=0x3f3f3f3f;
7 class Sap { ///最大流 O(MV*ME^2)
8 typedef int typef;///流量的类型
9 static const int ME=4010;///边的个数
10 static const int MV=64;///点的个数
11 int n,dep[MV],gap[MV],cur[MV],S[MV],top,i,inser;
12 typef flow;
13 queue<int> q;
14 void bfs(int s,int t) {
15 mt(dep,-1);
16 mt(gap,0);
17 while(!q.empty()) q.pop();
18 gap[0]=1;
19 dep[t]=0;
20 q.push(t);
21 while(!q.empty()) {
22 int u=q.front();
23 q.pop();
24 for(int i=g.head[u]; ~i; i=g.e[i].next) {
25 int v=g.e[i].v;
26 if(dep[v]!=-1) continue;
27 q.push(v);
28 dep[v]=dep[u]+1;
29 ++gap[dep[v]];
30 }
31 }
32 }
33 struct G {
34 struct E {
35 int u,v,next;
36 typef flow;
37 } e[ME];
38 int le,head[MV];
39 void init() {
40 le=0;
41 mt(head,-1);
42 }
43 void add(int u,int v,typef flow) {
44 e[le].u=u;
45 e[le].v=v;
46 e[le].flow=flow;
47 e[le].next=head[u];
48 head[u]=le++;
49 }
50 } g;
51 public:
52 void init(int tn) {///传入点的个数
53 n=tn;
54 g.init();
55 }
56 void add(int u,int v,typef flow) {
57 g.add(u,v,flow);
58 g.add(v,u,0);
59 }
60 typef solve(int s,int t) {
61 bfs(s,t);
62 flow=top=0;
63 for(i=0;i<=n;i++) cur[i]=g.head[i];
64 int u=s;
65 while(dep[s]<n) {
66 if(u==t) {
67 int temp=inf;
68 for(i=0; i<top; i++)
69 if(temp>g.e[S[i]].flow) {
70 temp=g.e[S[i]].flow;
71 inser=i;
72 }
73 for(i=0; i<top; i++) {
74 g.e[S[i]].flow-=temp;
75 g.e[S[i]^1].flow+=temp;
76 }
77 flow+=temp;
78 top=inser;
79 u=g.e[S[top]].u;
80 }
81 if(u!=t&&!gap[dep[u]-1]) break;
82 for(i=cur[u]; ~i; i=g.e[i].next)
83 if(g.e[i].flow&&dep[u]==dep[g.e[i].v]+1)
84 break;
85 if(~i) {
86 cur[u]=i;
87 S[top++]=i;
88 u=g.e[i].v;
89 } else {
90 int sma=n;
91 for(i=g.head[u]; ~i; i=g.e[i].next) {
92 if(!g.e[i].flow) continue;
93 int v=g.e[i].v;
94 if(sma>dep[v]) {
95 sma=dep[v];
96 cur[u]=i;
97 }
98 }
99 --gap[dep[u]];
100 dep[u]=sma+1;
101 ++gap[dep[u]];
102 if(u!=s) u=g.e[S[--top]].u;
103 }
104 }
105 return flow;
106 }
107 }sap;
108 int main() {
109 int t,n,m,p,q,x,y,z;
110 while(~scanf("%d",&t)) {
111 while(t--) {
112 scanf("%d%d%d%d",&n,&m,&p,&q);
113 sap.init(n);
114 int sum=0;
115 for(int i=0; i<m; i++) {
116 scanf("%d%d%d",&x,&y,&z);
117 sap.add(x,y,z*2000+1);
118 sap.add(y,x,z*2000+1);
119 sum+=z;
120 }
121 int ans=sap.solve(p,q);
122 int ans1 = ans/2000;//我是把边的权值乘以2000, 然后+1
123 int ans2 = ans%2000;//这样%2000就是最小割的边数, /2000就是最小割了。
124 if(ans == 0)printf("Inf
");
125 else printf("%.2f
",(sum-ans1)*1.0/ans2);
126 }
127 }
128 return 0;
129 }
View Code
poj 1273 Drainage Ditches http://poj.org/problem?id=1273 and hdu1532 http://acm.hdu.edu.cn/showproblem.php?pid=1532
模板题。
dinic
1 #include<cstdio>
2 #include<cstring>
3 #include<queue>
4 #define mt(a,b) memset(a,b,sizeof(a))
5 using namespace std;
6 const int inf=0x3f3f3f3f;
7 class Dinic { ///最大流(MV^2*ME)
8 typedef int typef;///流量的类型
9 static const int ME=512;///边的个数
10 static const int MV=256;///点的个数
11 int temp[MV],cur[MV],level[MV],path[MV];
12 bool used[MV];
13 queue<int> q;
14 typef flow;
15 bool bfs(int s,int t) {
16 mt(level,-1);
17 while(!q.empty()) q.pop();
18 q.push(s);
19 level[s]=1;
20 while(!q.empty()) {
21 int u=q.front();
22 q.pop();
23 for(int i=g.head[u]; ~i; i=g.e[i].next) {
24 int v=g.e[i].v;
25 if(level[v]==-1&&g.e[i].flow) {
26 level[v]=level[u]+1;
27 q.push(v);
28 if(v==t) return true;
29 }
30 }
31 }
32 return false;
33 }
34 struct G {
35 struct E {
36 int u,v,next;
37 typef flow;
38 } e[ME];
39 int le,head[MV];
40 void init() {
41 le=0;
42 mt(head,-1);
43 }
44 void add(int u,int v,typef flow) {
45 e[le].u=u;
46 e[le].v=v;
47 e[le].flow=flow;
48 e[le].next=head[u];
49 head[u]=le++;
50 }
51 } g;
52 public:
53 typef getflow() {
54 return flow;
55 }
56 void init() {
57 g.init();
58 }
59 void add(int u,int v,typef flow) {
60 g.add(u,v,flow);
61 g.add(v,u,0);
62 }
63 void solve(int s,int t) {
64 int p,tempp;
65 typef now;
66 bool flag;
67 flow=0;
68 while(bfs(s,t)) {
69 for(int i=0; i<MV; i++) {
70 temp[i]=g.head[i];
71 used[i]=true;
72 }
73 p=1;
74 path[p]=s;
75 while(p) {
76 int u=path[p];
77 if(u==t) {
78 now=inf;
79 for(int i=1; i<p; i++) {
80 now=min(now,g.e[cur[path[i]]].flow);
81 }
82 flow+=now;
83 for(int i=1; i<p; i++) {
84 int j=cur[path[i]];
85 g.e[j].flow-=now;
86 g.e[j^1].flow+=now;
87 if(!g.e[j].flow) tempp=i;
88 }
89 p=tempp;
90 } else {
91 flag=false;
92 for(int i=temp[u]; ~i; i=g.e[i].next) {
93 int v=g.e[i].v;
94 if(used[v]&&g.e[i].flow&&level[u]+1==level[v]) {
95 cur[u]=i;
96 temp[u]=g.e[i].next;
97 flag=true;
98 path[++p]=v;
99 break;
100 }
101 }
102 if(flag) continue;
103 p--;
104 used[u]=false;
105 }
106 }
107 }
108 }
109 } dinic;
110 int main(){
111 int m,n,u,v,w;
112 while(~scanf("%d%d",&m,&n)){
113 dinic.init();
114 while(m--){
115 scanf("%d%d%d",&u,&v,&w);
116 dinic.add(u,v,w);
117 }
118 dinic.solve(1,n);
119 printf("%d
",dinic.getflow());
120 }
121 return 0;
122 }
View Code
sap
1 #include<cstdio>
2 #include<cstring>
3 #include<queue>
4 #define mt(a,b) memset(a,b,sizeof(a))
5 using namespace std;
6 const int inf=0x3f3f3f3f;
7 class Sap { ///最大流 O(MV*ME^2)
8 typedef int typef;///流量的类型
9 static const int ME=512;///边的个数
10 static const int MV=256;///点的个数
11 int n,dep[MV],gap[MV],cur[MV],S[MV],top,i,inser;
12 typef flow;
13 queue<int> q;
14 void bfs(int s,int t) {
15 mt(dep,-1);
16 mt(gap,0);
17 while(!q.empty()) q.pop();
18 gap[0]=1;
19 dep[t]=0;
20 q.push(t);
21 while(!q.empty()) {
22 int u=q.front();
23 q.pop();
24 for(int i=g.head[u]; ~i; i=g.e[i].next) {
25 int v=g.e[i].v;
26 if(dep[v]!=-1) continue;
27 q.push(v);
28 dep[v]=dep[u]+1;
29 ++gap[dep[v]];
30 }
31 }
32 }
33 struct G {
34 struct E {
35 int u,v,next;
36 typef flow;
37 } e[ME];
38 int le,head[MV];
39 void init() {
40 le=0;
41 mt(head,-1);
42 }
43 void add(int u,int v,typef flow) {
44 e[le].u=u;
45 e[le].v=v;
46 e[le].flow=flow;
47 e[le].next=head[u];
48 head[u]=le++;
49 }
50 } g;
51 public:
52 void init(int tn) {///传入点的个数
53 n=tn;
54 g.init();
55 }
56 void add(int u,int v,typef flow) {
57 g.add(u,v,flow);
58 g.add(v,u,0);
59 }
60 typef solve(int s,int t) {
61 bfs(s,t);
62 flow=top=0;
63 for(i=0;i<=n;i++) cur[i]=g.head[i];
64 int u=s;
65 while(dep[s]<n) {
66 if(u==t) {
67 int temp=inf;
68 for(i=0; i<top; i++)
69 if(temp>g.e[S[i]].flow) {
70 temp=g.e[S[i]].flow;
71 inser=i;
72 }
73 for(i=0; i<top; i++) {
74 g.e[S[i]].flow-=temp;
75 g.e[S[i]^1].flow+=temp;
76 }
77 flow+=temp;
78 top=inser;
79 u=g.e[S[top]].u;
80 }
81 if(u!=t&&!gap[dep[u]-1]) break;
82 for(i=cur[u]; ~i; i=g.e[i].next)
83 if(g.e[i].flow&&dep[u]==dep[g.e[i].v]+1)
84 break;
85 if(~i) {
86 cur[u]=i;
87 S[top++]=i;
88 u=g.e[i].v;
89 } else {
90 int sma=n;
91 for(i=g.head[u]; ~i; i=g.e[i].next) {
92 if(!g.e[i].flow) continue;
93 int v=g.e[i].v;
94 if(sma>dep[v]) {
95 sma=dep[v];
96 cur[u]=i;
97 }
98 }
99 --gap[dep[u]];
100 dep[u]=sma+1;
101 ++gap[dep[u]];
102 if(u!=s) u=g.e[S[--top]].u;
103 }
104 }
105 return flow;
106 }
107 }sap;
108 int main(){
109 int m,n,u,v,w;
110 while(~scanf("%d%d",&m,&n)){
111 sap.init(n);
112 while(m--){
113 scanf("%d%d%d",&u,&v,&w);
114 sap.add(u,v,w);
115 }
116 printf("%d
",sap.solve(1,n));
117 }
118 return 0;
119 }
View Code
hdu 3549 Flow Problem http://acm.hdu.edu.cn/showproblem.php?pid=3549
模板
dinic
1 #include<cstdio>
2 #include<cstring>
3 #include<queue>
4 #define mt(a,b) memset(a,b,sizeof(a))
5 using namespace std;
6 const int inf=0x3f3f3f3f;
7 class Dinic { ///最大流(MV^2*ME)
8 typedef int typef;///流量的类型
9 static const int ME=2010;///边的个数
10 static const int MV=16;///点的个数
11 int temp[MV],cur[MV],level[MV],path[MV];
12 bool used[MV];
13 queue<int> q;
14 typef flow;
15 bool bfs(int s,int t) {
16 mt(level,-1);
17 while(!q.empty()) q.pop();
18 q.push(s);
19 level[s]=1;
20 while(!q.empty()) {
21 int u=q.front();
22 q.pop();
23 for(int i=g.head[u]; ~i; i=g.e[i].next) {
24 int v=g.e[i].v;
25 if(level[v]==-1&&g.e[i].flow) {
26 level[v]=level[u]+1;
27 q.push(v);
28 if(v==t) return true;
29 }
30 }
31 }
32 return false;
33 }
34 struct G {
35 struct E {
36 int u,v,next;
37 typef flow;
38 } e[ME];
39 int le,head[MV];
40 void init() {
41 le=0;
42 mt(head,-1);
43 }
44 void add(int u,int v,typef flow) {
45 e[le].u=u;
46 e[le].v=v;
47 e[le].flow=flow;
48 e[le].next=head[u];
49 head[u]=le++;
50 }
51 } g;
52 public:
53 typef getflow() {
54 return flow;
55 }
56 void init() {
57 g.init();
58 }
59 void add(int u,int v,typef flow) {
60 g.add(u,v,flow);
61 g.add(v,u,0);
62 }
63 void solve(int s,int t) {
64 int p,tempp;
65 typef now;
66 bool flag;
67 flow=0;
68 while(bfs(s,t)) {
69 for(int i=0; i<MV; i++) {
70 temp[i]=g.head[i];
71 used[i]=true;
72 }
73 p=1;
74 path[p]=s;
75 while(p) {
76 int u=path[p];
77 if(u==t) {
78 now=inf;
79 for(int i=1; i<p; i++) {
80 now=min(now,g.e[cur[path[i]]].flow);
81 }
82 flow+=now;
83 for(int i=1; i<p; i++) {
84 int j=cur[path[i]];
85 g.e[j].flow-=now;
86 g.e[j^1].flow+=now;
87 if(!g.e[j].flow) tempp=i;
88 }
89 p=tempp;
90 } else {
91 flag=false;
92 for(int i=temp[u]; ~i; i=g.e[i].next) {
93 int v=g.e[i].v;
94 if(used[v]&&g.e[i].flow&&level[u]+1==level[v]) {
95 cur[u]=i;
96 temp[u]=g.e[i].next;
97 flag=true;
98 path[++p]=v;
99 break;
100 }
101 }
102 if(flag) continue;
103 p--;
104 used[u]=false;
105 }
106 }
107 }
108 }
109 } dinic;
110 int main() {
111 int T,n,m,x,y,z;
112 while(~scanf("%d",&T)){
113 int cas=1;
114 while(T--){
115 scanf("%d%d",&n,&m);
116 dinic.init();
117 while(m--){
118 scanf("%d%d%d",&x,&y,&z);
119 dinic.add(x,y,z);
120 }
121 dinic.solve(1,n);
122 printf("Case %d: %d
",cas++,dinic.getflow());
123 }
124 }
125 return 0;
126 }
View Code
sap
1 #include<cstdio>
2 #include<cstring>
3 #include<queue>
4 #define mt(a,b) memset(a,b,sizeof(a))
5 using namespace std;
6 const int inf=0x3f3f3f3f;
7 class Sap { ///最大流 O(MV*ME^2)
8 typedef int typef;///流量的类型
9 static const int ME=2010;///边的个数
10 static const int MV=16;///点的个数
11 int n,dep[MV],gap[MV],cur[MV],S[MV],top,i,inser;
12 typef flow;
13 queue<int> q;
14 void bfs(int s,int t) {
15 mt(dep,-1);
16 mt(gap,0);
17 while(!q.empty()) q.pop();
18 gap[0]=1;
19 dep[t]=0;
20 q.push(t);
21 while(!q.empty()) {
22 int u=q.front();
23 q.pop();
24 for(int i=g.head[u]; ~i; i=g.e[i].next) {
25 int v=g.e[i].v;
26 if(dep[v]!=-1) continue;
27 q.push(v);
28 dep[v]=dep[u]+1;
29 ++gap[dep[v]];
30 }
31 }
32 }
33 struct G {
34 struct E {
35 int u,v,next;
36 typef flow;
37 } e[ME];
38 int le,head[MV];
39 void init() {
40 le=0;
41 mt(head,-1);
42 }
43 void add(int u,int v,typef flow) {
44 e[le].u=u;
45 e[le].v=v;
46 e[le].flow=flow;
47 e[le].next=head[u];
48 head[u]=le++;
49 }
50 } g;
51 public:
52 void init(int tn) {///传入点的个数
53 n=tn;
54 g.init();
55 }
56 void add(int u,int v,typef flow) {
57 g.add(u,v,flow);
58 g.add(v,u,0);
59 }
60 typef solve(int s,int t) {
61 bfs(s,t);
62 flow=top=0;
63 for(i=0;i<=n;i++) cur[i]=g.head[i];
64 int u=s;
65 while(dep[s]<n) {
66 if(u==t) {
67 int temp=inf;
68 for(i=0; i<top; i++)
69 if(temp>g.e[S[i]].flow) {
70 temp=g.e[S[i]].flow;
71 inser=i;
72 }
73 for(i=0; i<top; i++) {
74 g.e[S[i]].flow-=temp;
75 g.e[S[i]^1].flow+=temp;
76 }
77 flow+=temp;
78 top=inser;
79 u=g.e[S[top]].u;
80 }
81 if(u!=t&&!gap[dep[u]-1]) break;
82 for(i=cur[u]; ~i; i=g.e[i].next)
83 if(g.e[i].flow&&dep[u]==dep[g.e[i].v]+1)
84 break;
85 if(~i) {
86 cur[u]=i;
87 S[top++]=i;
88 u=g.e[i].v;
89 } else {
90 int sma=n;
91 for(i=g.head[u]; ~i; i=g.e[i].next) {
92 if(!g.e[i].flow) continue;
93 int v=g.e[i].v;
94 if(sma>dep[v]) {
95 sma=dep[v];
96 cur[u]=i;
97 }
98 }
99 --gap[dep[u]];
100 dep[u]=sma+1;
101 ++gap[dep[u]];
102 if(u!=s) u=g.e[S[--top]].u;
103 }
104 }
105 return flow;
106 }
107 }sap;
108 int main() {
109 int T,n,m,x,y,z;
110 while(~scanf("%d",&T)){
111 int cas=1;
112 while(T--){
113 scanf("%d%d",&n,&m);
114 sap.init(n);
115 while(m--){
116 scanf("%d%d%d",&x,&y,&z);
117 sap.add(x,y,z);
118 }
119 printf("Case %d: %d
",cas++,sap.solve(1,n));
120 }
121 }
122 return 0;
123 }
View Code
csu 1433: Defend the Bases http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1433
二分图匹配。用最大流来求最大匹配数。先二分时间,就是二分答案,然后对于mid这个时间,可以建图跑看能否满流。
dinic
1 #include<cstdio>
2 #include<cstring>
3 #include<cmath>
4 #include<queue>
5 #define mt(a,b) memset(a,b,sizeof(a))
6 using namespace std;
7 const int inf=0x3f3f3f3f;
8 const int M=128;
9 const double eps=1e-12;
10 class Dinic { ///最大流(MV^2*ME)
11 typedef int typef;///流量的类型
12 static const int ME=M*M*2;///边的个数
13 static const int MV=M*M;///点的个数
14 int temp[MV],cur[MV],level[MV],path[MV];
15 bool used[MV];
16 queue<int> q;
17 typef flow;
18 bool bfs(int s,int t) {
19 mt(level,-1);
20 while(!q.empty()) q.pop();
21 q.push(s);
22 level[s]=1;
23 while(!q.empty()) {
24 int u=q.front();
25 q.pop();
26 for(int i=g.head[u]; ~i; i=g.e[i].next) {
27 int v=g.e[i].v;
28 if(level[v]==-1&&g.e[i].flow) {
29 level[v]=level[u]+1;
30 q.push(v);
31 if(v==t) return true;
32 }
33 }
34 }
35 return false;
36 }
37 struct G {
38 struct E {
39 int u,v,next;
40 typef flow;
41 } e[ME];
42 int le,head[MV];
43 void init() {
44 le=0;
45 mt(head,-1);
46 }
47 void add(int u,int v,typef flow) {
48 e[le].u=u;
49 e[le].v=v;
50 e[le].flow=flow;
51 e[le].next=head[u];
52 head[u]=le++;
53 }
54 } g;
55 public:
56 typef getflow() {
57 return flow;
58 }
59 void init() {
60 g.init();
61 }
62 void add(int u,int v,typef flow) {
63 g.add(u,v,flow);
64 g.add(v,u,0);
65 }
66 void solve(int s,int t) {
67 int p,tempp;
68 typef now;
69 bool flag;
70 flow=0;
71 while(bfs(s,t)) {
72 for(int i=0; i<MV; i++) {
73 temp[i]=g.head[i];
74 used[i]=true;
75 }
76 p=1;
77 path[p]=s;
78 while(p) {
79 int u=path[p];
80 if(u==t) {
81 now=inf;
82 for(int i=1; i<p; i++) {
83 now=min(now,g.e[cur[path[i]]].flow);
84 }
85 flow+=now;
86 for(int i=1; i<p; i++) {
87 int j=cur[path[i]];
88 g.e[j].flow-=now;
89 g.e[j^1].flow+=now;
90 if(!g.e[j].flow) tempp=i;
91 }
92 p=tempp;
93 } else {
94 flag=false;
95 for(int i=temp[u]; ~i; i=g.e[i].next) {
96 int v=g.e[i].v;
97 if(used[v]&&g.e[i].flow&&level[u]+1==level[v]) {
98 cur[u]=i;
99 temp[u]=g.e[i].next;
100 flag=true;
101 path[++p]=v;
102 break;
103 }
104 }
105 if(flag) continue;
106 p--;
107 used[u]=false;
108 }
109 }
110 }
111 }
112 } dinic;
113 struct G{
114 double x,y,v;
115 }jun[M],base[M];
116 int main() {
117 int n,m;
118 while(~scanf("%d%d",&n,&m)) {
119 for(int i=1; i<=n; i++) {
120 scanf("%lf%lf%lf",&jun[i].x,&jun[i].y,&jun[i].v);
121 }
122 for(int i=1; i<=m; i++) {
123 scanf("%lf%lf",&base[i].x,&base[i].y);
124 }
125 double L=0,R=inf;
126 double ans=inf;
127 while(L<=R) {
128 int s=0,t=n+n+m;
129 double mid=(L+R)/2;
130 dinic.init();
131 for(int i=1; i<=n; i++) {
132 dinic.add(s,i,1);
133 }
134 for(int i=1; i<=m; i++) {
135 dinic.add(n+i,t,1);
136 }
137 for(int i=1; i<=n; i++) {
138 for(int j=1; j<=m; j++) {
139 double dx=jun[i].x-base[j].x;
140 double dy=jun[i].y-base[j].y;
141 double dir=sqrt(dx*dx+dy*dy)/jun[i].v;
142 if(dir<=mid) {
143 dinic.add(i,n+j,1);
144 }
145 }
146 }
147 dinic.solve(s,t);
148 if(dinic.getflow()==m) {
149 ans=min(ans,mid);
150 R=mid-eps;
151 } else {
152 L=mid+eps;
153 }
154 }
155 printf("%.11f
",ans);
156 }
157 return 0;
158 }
View Code
sap
1 #include<cstdio>
2 #include<cstring>
3 #include<cmath>
4 #include<queue>
5 #define mt(a,b) memset(a,b,sizeof(a))
6 using namespace std;
7 const int inf=0x3f3f3f3f;
8 const int M=128;
9 const double eps=1e-12;
10 class Sap { ///最大流 O(MV*ME^2)
11 typedef int typef;///流量的类型
12 static const int ME=M*M*2;///边的个数
13 static const int MV=M*M;///点的个数
14 int n,dep[MV],gap[MV],cur[MV],S[MV],top,i,inser;
15 typef flow;
16 queue<int> q;
17 void bfs(int s,int t) {
18 mt(dep,-1);
19 mt(gap,0);
20 while(!q.empty()) q.pop();
21 gap[0]=1;
22 dep[t]=0;
23 q.push(t);
24 while(!q.empty()) {
25 int u=q.front();
26 q.pop();
27 for(int i=g.head[u]; ~i; i=g.e[i].next) {
28 int v=g.e[i].v;
29 if(dep[v]!=-1) continue;
30 q.push(v);
31 dep[v]=dep[u]+1;
32 ++gap[dep[v]];
33 }
34 }
35 }
36 struct G {
37 struct E {
38 int u,v,next;
39 typef flow;
40 } e[ME];
41 int le,head[MV];
42 void init() {
43 le=0;
44 mt(head,-1);
45 }
46 void add(int u,int v,typef flow) {
47 e[le].u=u;
48 e[le].v=v;
49 e[le].flow=flow;
50 e[le].next=head[u];
51 head[u]=le++;
52 }
53 } g;
54 public:
55 void init(int tn) {///传入点的个数
56 n=tn;
57 g.init();
58 }
59 void add(int u,int v,typef flow) {
60 g.add(u,v,flow);
61 g.add(v,u,0);
62 }
63 typef solve(int s,int t) {
64 bfs(s,t);
65 flow=top=0;
66 for(i=0;i<=n;i++) cur[i]=g.head[i];
67 int u=s;
68 while(dep[s]<n) {
69 if(u==t) {
70 int temp=inf;
71 for(i=0; i<top; i++)
72 if(temp>g.e[S[i]].flow) {
73 temp=g.e[S[i]].flow;
74 inser=i;
75 }
76 for(i=0; i<top; i++) {
77 g.e[S[i]].flow-=temp;
78 g.e[S[i]^1].flow+=temp;
79 }
80 flow+=temp;
81 top=inser;
82 u=g.e[S[top]].u;
83 }
84 if(u!=t&&!gap[dep[u]-1]) break;
85 for(i=cur[u]; ~i; i=g.e[i].next)
86 if(g.e[i].flow&&dep[u]==dep[g.e[i].v]+1)
87 break;
88 if(~i) {
89 cur[u]=i;
90 S[top++]=i;
91 u=g.e[i].v;
92 } else {
93 int sma=n;
94 for(i=g.head[u]; ~i; i=g.e[i].next) {
95 if(!g.e[i].flow) continue;
96 int v=g.e[i].v;
97 if(sma>dep[v]) {
98 sma=dep[v];
99 cur[u]=i;
100 }
101 }
102 --gap[dep[u]];
103 dep[u]=sma+1;
104 ++gap[dep[u]];
105 if(u!=s) u=g.e[S[--top]].u;
106 }
107 }
108 return flow;
109 }
110 }sap;
111 struct G{
112 double x,y,v;
113 }jun[M],base[M];
114 int main() {
115 int n,m;
116 while(~scanf("%d%d",&n,&m)) {
117 for(int i=1; i<=n; i++) {
118 scanf("%lf%lf%lf",&jun[i].x,&jun[i].y,&jun[i].v);
119 }
120 for(int i=1; i<=m; i++) {
121 scanf("%lf%lf",&base[i].x,&base[i].y);
122 }
123 double L=0,R=inf;
124 double ans=inf;
125 while(L<=R) {
126 int s=0,t=n+n+m;
127 double mid=(L+R)/2;
128 sap.init(n+m+2);
129 for(int i=1; i<=n; i++) {
130 sap.add(s,i,1);
131 }
132 for(int i=1; i<=m; i++) {
133 sap.add(n+i,t,1);
134 }
135 for(int i=1; i<=n; i++) {
136 for(int j=1; j<=m; j++) {
137 double dx=jun[i].x-base[j].x;
138 double dy=jun[i].y-base[j].y;
139 double dir=sqrt(dx*dx+dy*dy)/jun[i].v;
140 if(dir<=mid) {
141 sap.add(i,n+j,1);
142 }
143 }
144 }
145 if(sap.solve(s,t)==m) {
146 ans=min(ans,mid);
147 R=mid-eps;
148 } else {
149 L=mid+eps;
150 }
151 }
152 printf("%.11f
",ans);
153 }
154 return 0;
155 }
View Code
二分图最大匹配
1 #include<cstdio>
2 #include<cmath>
3 #include<algorithm>
4 using namespace std;
5 ///1. 最大匹配数+ 最大独立集= n + m
6 ///2: 二分图的最小点覆盖 = 最大匹配数
7 ///3: 最小路径覆盖= 最大独立集
8 ///最大独立集是指求一个二分图中最大的一个点集,该点集内的点互不相连。
9 ///最小顶点覆盖是指在二分图中,用最少的点,让所有的边至少和一个点有关联。
10 ///最小路径覆盖是指一个不含圈的有向图G 中,图中的每一个结点仅包含于P 中的一条路径中。
11 class Bipartite_graph { ///二分图最大匹配_匈牙利算法_O(MV^3)
12 static const int MV=1e2+10;///点的个数max(x,y)
13 bool mat[MV][MV],vis[MV];
14 int res[MV],n,m,big;///res[]存y部匹配的x部的下标
15 bool dfs(int a) {
16 for (int i=0; i<=m; i++) {
17 if (mat[a][i]&&!vis[i]) {
18 vis[i]=true;
19 if(res[i]==-1||dfs(res[i])) {
20 res[i]=a;
21 return true;
22 }
23 }
24 }
25 return false;
26 }
27 public:
28 void init(int x,int y) {///传入x部和y部点数
29 n=x;
30 m=y;
31 for(int i=0;i<=x;i++){
32 for(int j=0;j<=y;j++){
33 mat[i][j]=false;
34 }
35 res[i]=-1;
36 }
37 }
38 void add(int u,int v) {
39 mat[u][v]=true;
40 }
41 int solve() {
42 big=0;
43 for(int i=0; i<=n; i++) {
44 for(int j=0;j<=m;j++) vis[j]=false;
45 if(dfs(i)) big++;
46 }
47 return big;
48 }
49 } gx;
50
51 const int M=128;
52 const int inf=0x3f3f3f3f;
53 const double eps=1e-12;
54 struct G{
55 double x,y,v;
56 }jun[M],base[M];
57 int main() {
58 int n,m;
59 while(~scanf("%d%d",&n,&m)) {
60 for(int i=1; i<=n; i++) {
61 scanf("%lf%lf%lf",&jun[i].x,&jun[i].y,&jun[i].v);
62 }
63 for(int i=1; i<=m; i++) {
64 scanf("%lf%lf",&base[i].x,&base[i].y);
65 }
66 double L=0,R=inf;
67 double ans=inf;
68 while(L<=R) {
69 int s=0,t=n+n+m;
70 double mid=(L+R)/2;
71 gx.init(n,m);
72 for(int i=1; i<=n; i++) {
73 for(int j=1; j<=m; j++) {
74 double dx=jun[i].x-base[j].x;
75 double dy=jun[i].y-base[j].y;
76 double dir=sqrt(dx*dx+dy*dy)/jun[i].v;
77 if(dir<=mid) {
78 gx.add(i,j);
79 }
80 }
81 }
82 if(gx.solve()==m) {
83 ans=min(ans,mid);
84 R=mid-eps;
85 } else {
86 L=mid+eps;
87 }
88 }
89 printf("%.11f
",ans);
90 }
91 return 0;
92 }
View Code
end