最大流最小割

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

相关推荐