最大流最小割
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\n"); 130 else printf("%.2f\n",(sum-ans1)*1.0/ans2); 131 } 132 } 133 return 0; 134 }
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\n"); 125 else printf("%.2f\n",(sum-ans1)*1.0/ans2); 126 } 127 } 128 return 0; 129 }
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\n",dinic.getflow()); 120 } 121 return 0; 122 }
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\n",sap.solve(1,n)); 117 } 118 return 0; 119 }
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\n",cas++,dinic.getflow()); 123 } 124 } 125 return 0; 126 }
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\n",cas++,sap.solve(1,n)); 120 } 121 } 122 return 0; 123 }
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\n",ans); 156 } 157 return 0; 158 }
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\n",ans); 153 } 154 return 0; 155 }
二分图最大匹配
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\n",ans); 90 } 91 return 0; 92 }
end